Heuristics for Effective Software Development: A continuously evolving list
holub.com
holub.com
That was 4 years ago. First the timeline got pushed out, then I rather gather he's just got bored and drifted on.
How ironic is the non-delivery of an agile training course, supposedly delivered in an agile way, that utterly fails to actually, y'know, deliver?
[]1 https://www.kickstarter.com/projects/1086486319/agility-with...
> November 2, 2017
Lol
Don't get me wrong, I've found a lot of Holub's content to be great. I'm something of a fan in some senses, as it's given me a perspective to question some of the utter guff prevalent in the agile space (particularly wrt. things like Scrum and Story points). I don't buy some of it - things like cost of delay - but I'm always interested to hear more and I'm prepared to change my mind on it.
But.
Much like Dawkins, he ought to stay off twitter, as he comes out with crazy-town absolutist statements (like: if your organisation doesn't do X, then it's fundamentally beyond all redemption and you should just leave).
A recurring theme is there in that list, particularly (20), which is - to paraphrase - "give all your money to the agile team, then go away and you have no right to question what they're doing in any way, shape, or form - you just trust them to 'do the right thing' as they're the experts". No line management, no project management, nothing. Go away and leave me alone.
Now put that in context of a self started project that took nearly $15K, listed no significant risks "hey I already have most of this content anyway", has no external dependencies to blame and... completely failed to deliver. How can I take any of it seriously when the supposed expert can so utterly fail to practice what they are preaching?
> External pressure (accountability) and internal pressure (responsibility) are simply not needed in a healthy culture. As in a relationship, the word “accountable” is rarely, if ever, heard in high functioning organizations.
I can't quite determine if he is ahead of his time or a snake oil salesman.
For me responsibility is a key component of getting shit done. You do need an environment where fear is driven or so that if someone feels they can not fulfil they're responsibility they can come forward for support. But in my experience if everyone is responsible for something it often ends up no one is.
Accountability should not nearly be as negative and adversarial as Alan portrays though it is admittedly often treading a fine line. As a leader i try to be accountable for my area of responsibility and aim to filter external blame from the team. I encourage my team to be introspective about our processes and to continually improve, I definitely don't find finger pointing helpful.
"Real artists ship."
I just don’t get, after decades and decades, how our industry continues to tolerate bullshit.
Quality is not negotiable? Really? Negotiation is not collaboration? Really? This is not just wrong, it’s almost gaslighting.
Simple is a very relative thing, qnd not everything can be "simple". Not everything is a transient thing, especially if you're trying to improve ypur customers lives. Tinkering qith parts is often the only way to improve a system and setting your sights on changing everything at once is setting yourself up for being overwhelmed.
It's just one overly-dogmatic, "new age bs" after another with little though to what the consequences of these heuristics would be.
The problem is not just that we tolerate bullshit: we reward it. I'd bet he gets paid quite handsomely to trot out this bilge.
Here's a thing close to my heart: "Knowledge work has unique concerns, unrelated to those of a factory or construction site." But notice how he doesn't talk about any specifics, or recognise that there are shades of difference in knowledge work: e.g., it's easier to make determinations about delivery when adding well-understood and tightly scoped CRUD pages, than it is when delivering a more R&D oriented outcome. Don't get me started on the Toyota nonsense though because we'll be here all day.
Another bugbear: talking about outcome versus output without being specific about what you mean with these terms. Grr. And the first point about processes: they don't serve people, they serve business outcomes. Sometimes those things coincide; often they don't.
I read this as "certain principles must be upheld at any cost" and I agree with that. E.g. if your project is dealing with people's health data, not securing that database is a cut on quality you just shouldn't make. Or to phrase it the other way around: If your project cannot reach that basic quality level, maybe it should be ended right away, because it clearly lacks funding/resources. As a freelancer I wouldn't take that job.
> Negotiation is not collaboration? Really?
Well it can be, but it also can't be. The phrasing on this one is a bit vague. But if you read it as "just defending your interest and not trying to discuss common goals and the goals of the other side is not collaboration" it would be true again.
That's a commendable character trait, but if you have to twist a "heuristic" beyond recognizability for it to make any sense, then what's the purpose of that heuristic?
Otherwise what are we saying the causality is? Like, that the list is just somehow inspiring everyone to be successful? So, like, if we just believe enough in the list we'll get it done? No thanks. I'm not going to pray to some poetry.
> I read this as "certain principles must be upheld at any cost" and I agree with that.
But that's you reading things that aren't in the text. And by itself, it's not a good principle either:
- "certain principles" - which principles exactly? Of them, which ones are related to quality?
- "must be upheld at any cost" - any cost? There's few things in life that truly "must be upheld at any cost", and they're in the scope of morality, not software. Even "thou shalt not kill" is full of practical caveats.
Everything in software engineering is negotiable, all principles have a price. The important parts are all in the details: what exact principles we have, how they trade off against each other, what benefits do they bring, how much do they cost, how much is too much. This list doesn't touch any of it.
You continue:
> E.g. if your project is dealing with people's health data, not securing that database is a cut on quality you just shouldn't make.
Yes, now we're starting to see a glimpse of something useful - but it's still a bit too vague to work with. Consider:
- What is "health data" under consideration? For example, someone's smartwatch BPM and GPS log, a result of MRI scan, a list of visits at a clinic, and how old they are - these are all "health data", but fall into different qualitative categories, and merit different level of care in handling.
- What is "dealing with"? Storing? Forwarding? Processing? How? Giving access? To whom? Etc.
- What is "securing that database"? Are we talking access controls against the dev team? The company stakeholders? Securing against script kiddies? Securing against Mossad? In which particular way?
You may feel I'm splitting hairs here, but this is reality: quality is always negotiable, and day-to-day negotiations will happen at this level of granularity. Nobody has infinite budget to respond "yes" to any idea that could be presented as "increasing quality" or "increasing security of medical data".
Developing lists of principles and heuristics is of great value - but this list isn't that. The heuristics you want need to account for the reality we live in (including working around organizational dysfunctions and individual cognitive failures). And they need to be formulated in practical terms, or they'll forever be words on paper. Their only job is to help you answer the question, "is it worth it?", every time you consider two options of different quality.
I was working in VFX where you always had to talk about quality, yet I didn't take certain jobs, because below a certain quality level VFX make no sense anymore (unless bad FX are the point of the movie) — below a certain level you won't be happy, the customer won't be happy, it won't be work that you can show etc.
Granted: coming to this from "quality is not negotiable" is a far stretch, but that was the way I initially read it. Maybe a better heuristic would be "Below a certain quality level, don't bother"
I, too, make lists of heuristics. And one way I test them is to ask "how could this be completely wrong? Is this really what I mean?" The common idea of negotiation is the process of coming to an agreement by each side being willing to give up something they want (at least in principle) in order to achieve something else they do want. It seems to me that collaboration involves a great deal of negotiation. So, is the OP talking about BAD negotiation? Then say so.
There is nothing actionable about this list. A lot of it is meant to sound wise, without any specifics.
Definition of heuristics:
> A heuristic, or a heuristic technique, is any approach to problem-solving that uses a practical method or various shortcuts in order to produce solutions that may not be optimal but are sufficient given a limited timeframe or deadline.
A small sample of the heuristics from the "evolving list":
> Our only measure of progress is delivering into our customers hands things they find valuable.
> Outcomes matter more than output. A focus on output yields sub-par outcomes.
None of this is practical or a shortcut of any kind. It just "sounds" nice as an abstract idea.
This unfortunately applies to most of the popular advice in our industry. You could argue that "meant to be wise, without any specifics" is a requirement for a meme to get picked up and recognized by a large enough mass of people in order for it to become viral.
Consider if you can apply anything in SOLID in an actionable way. None of it is actionable, except LSP. It's meant to sound wise, without any specifics.
I have heard almost no advice that's anywhere near actionable in our industry. The way I see it is that we have no objective ways to even talk about good code versus bad code (and forget all of the support tasks like "can we estimate this"; those require some objective understanding on how terrible the code happens to be).
We've got code smells. Like, the most primitive and "from your gut" sense. This for-loop makes my tummy feel bad.
It all feels like poetry to me.
Bryan Cantrill (OS developer who used to work at sun microsystems) talks about how the C macros are great [1].
John Carmack talks about how long functions can be better than short ones [2].
Every piece of advice that I've heard has had a contradiction coming from a preeminent developer.
To be fair, yes, people do agree on bad practices. They are just often wrong. People agreeing that something is true doesn't make it that way.
[1] - I believe that he mentions that here however, I'm not sure. I have heard him mention it in more than one video. https://www.youtube.com/watch?v=LjFM8vw3pbU
[2] - http://number-none.com/blow/john_carmack_on_inlined_code.htm...
Sure there are exceptions to most rules, but break them only if you know what you are doing and are able to justify doing so.
I've recently had to work on a project controlled by someone who's swallowed "clean code" and a couple of C# style guides and now just unthinkingly applies what he thinks he's read. E.g: you are not allowed any comments in this codebase. No variable may be typed. Period.
Both extremes are.. not good.
Isn't this exactly the kind of vague advice that GP was talking about?
I haven't recovered since. For anyone interested, here is my notes summary from various articles and videos from John.
### John Carmack
* Do-always, then inhibit or ignore strategy
* Common pattern for me: get first results with hacky code, then write a brand new and clean implementation with the lessons learned, so they both exist and can be cross checked.
* If a function is only called from a single place, consider inlining it.
* If a function is called from multiple places, see if it is possible to arrange for the work to be done in a single place, perhaps with flags, and inline that.
* If there are multiple versions of a function, consider making a single function with more, possibly defaulted, parameters.
* If the work is close to purely functional, with few references to global state, try to make it completely functional.
* Try to use const on both parameters and functions when the function really must be used in multiple places.
* Minimize control flow complexity and "area under ifs", favoring consistent execution paths and times over "optimally" avoiding unnecessary work.
OOP started like that, as an initial concept it made a lot of sense. Try to force OOP into anything you have a problem. Functional Programming, is the counter to OOP design, but it also has problems.
Same is true to having short functions doing one thing vs abstracting too early. Our industry is filled with counter points.
Even the "recent" shift to microservices, taking to the extreme they create new problems that monoliths didn't have.
...this is one of my biggest struggles as a developer currently, conflicting ideas that all make sense and trying to figure out which one I should apply for a specific piece of code.
O - "Don't modify, extend instead."
I - "Don't group interfaces into a god object - separate them."
D - "Depend on abstractions not concrete implementations."
S is the most disputed but Uncle Bob occasionally clarifies (paraphrased, again): "Object definitions should be beholden to only one stakeholder group."
SOLID seems actionable enough to me... whereas Holub's article is a bunch of fluffy mothering statements.
But isn't this just stating the obvious, e.g. don't measure success by lines of code written, number of commits, number of bugs fixed...? And there is nothing wrong in stating the obvious, especially as when it is not obvious to some people.
There's enough nuance required here to fill a small series of books. If you state the obvious and then go on to actually examine the nuance, then I'm fine giving you credit. If you don't then I don't really see the benefit.
Worse, you've given people a thought terminating cliche that can be disastrous in the hands of a novice. "Hey, we're focusing on the outcomes!" Yeah, but you've missed three milestone dates so your funding is going to be pulled and everyone is now unemployed.
But you are really arguing in general against such lists like this, that don't "examine the nuance". But perhaps they are useful discussion point or memory joggers. And shouldn't the senior members of a team or managers explain to novices the importance of meeting such milestones that you mentioned?
I basically read the whole list as: "How do be successful? Step 1: Be successful. Step 2: Be successful at purple. etc"
Some of it sort of makes sense. Some of it might as well be gibberish. None of it is useful without a bunch of senior members of a team who have been successful before. And if that's the case, then we can just delete the list and stick with the senior members of the team.
I can see the use of such a list for example on a team wiki as a reminder of what the team considers good practice.
This is not "New age bullshit", although I understand the sentiment. The most frustrating part about studying how teams self-manage for success is that management theory consists of a lot of words and emotions and very little concrete theory. That doesn't make any of it wrong; it just makes it very difficult to discuss in the same logical way we'd discuss, say a new theorem.
What's missing here is any sort of agreed-upon discernment function. Psychological safety is important. Ok. But how do we tell when we have that versus when we don't? Process exists in service of people. Ok, what does that mean? Should a process, for instance, inform people of things they don't like or want to hear? I would think that if a process wasn't ever uncomfortable, it's not much of a good process. But then again, we don't know.
The entire list is mostly like that. It's not things you can disagree with, it all sounds pretty good, but as a reader you're left with an empty feeling. Just what the heck am I supposed to do with this?
There's an old saying that much of being a management consultant is pandering to a natural type of person who wants to burn it all down. The rest of it is just telling clients what they already want to hear. It doesn't give those folks a good reputation.
Once again, though, it doesn't mean any of it is wrong, it's just intractable. As much as mankind has tried over and over again, it remains barbarously difficult to translate feel-good things we all instinctively know that work into practical and actionable advice, at least when it comes to knowledge work. (For assembly-line production/manufacturing work the situation is different, thank goodness)
I believe there's a lot of overstatement on both sides of this discussion, a lot of posturing and demagogurely, even by people who mean well and don't realize what they're doing. It's not that there's nothing there, it's that there is a lot of work still remaining. This is too important for all of us to simply bounce around off-the-walls about. There's something of value there. Let's go find it.
1. If you're interested in my weekly roundup, shameless plug: https://danielbmarkham.com
Have you looked at http://nim-lang.org ?
This comes out in #13, #19, and #20 (well depending on exactly what they mean by "managing".) I find it really helps to have someone dedicated to the product side, so they can help with prioritization, generating ideas for what to try next, keeping track of the research, and tracking the launch process and metrics.
We could, I suppose, distribute all of that to the engineers, but there's value in that specialization.
(I generalize to "agile-folks" here because I feel like I've seen this before, but I can't think of exactly where.)
Let's say we have 4 domains, and 4 domain experts. P is product, B is backend, F is frontend, and D is database(this is heavily simplifying, I know there are many sub-domains within each depending on the scope of the project). Each new feature starts with the P expert working with the team translating the user requirements into what he thinks is needed. B and F communicate with each other. B and D communicate with each other. But since none of them have a shared understanding, the communication is of poor quality. You get mistakes. You'll find that if you had an PF expert the implementation would be 10x simpler. You get things where if you had an PBFD expert would be 1 million times simpler. Without the cross-domain knowledge you will never know when those simplifying measure are possible.
The problem with starting with a P is that the expert is basically starving the rest of the team of the knowledge that they have accumulated. They handle that work, it's up the the product expert to come up with the new features. And by putting that title on their head, and never letting the developers in, it tends to lock in place.
You are only as creative as your feedback loops, and your feedback loops depend on the bandwidth of communication. Within waterfall that might be months. Within agile that is a sprint. But with a PBFD expert your feedback loops can be measured in seconds.
You don't need PBFD experts, but it is very helpful to at least have translators. So there might be a PD expert, there might be a BF expert. That way you can get a reasonable translation of the requirement out. By taking on the team a Product Manager who is explicitly non-technical person, you lock that P in place. I think that's why we're seeing push-back to PM's where it's a general domain issue. P is a fine role, if you also have a PD, if you also have a PB, if you also have a PF. The Fullstack developer is already a BFD, why not also train them in the product?
The example I like to give is that Linus Torvalds created git in 10 days because he was a master user of Source Control and knew exactly what he needed while also able to create everything, while Microsoft's Source Control team had worked with hundreds of developers over years and couldn't compete. When you have hundreds working on a project the ability to communicate in a depth-first-search style drops to 0, and you are left to only breadth-first-search solutions. Metcalfe's Law destroys productivity.
But in my experience the PM is technical enough to understand what's going on. (Can write some SQL to answer questions, possibly ex-engineer themselves, etc.) They're in the same meetings, same email threads, looking at the same set of OKRs, etc. It's part of the engineers' jobs (B/F/D whatever) to communicate their constraints and their ideas (both product and pure-tech) to the PM, and it's part of the PM's job to take those into account when advocating for what should be done.
Similarly, the more the engineers know each others' specialties, the better they can coordinate. It's probably more important for everyone to have "a little bit of product" in them, but that doesn't mean we don't need a product-specialist.
When it's time for quarterly planning, the PM's voice is definitely loud, but they're still just one voice in the room. They're the one accountable for the product, which gives them some leverage, but the other voices are there (TLs, managers, etc.)
Now I can see this going terribly wrong if the scale is off (only one PM for too many engineers), or if communication breaks down (PM scribbles a "design" on a napkin and faxes it over), or if only the PM is consulted for planning. But the problem there is that communication broke down, not that it's bad to have a PM.
There was a PM post this last week[0] where I can cite possible flaws. The PM creating this post has engineering experience, so it's possible that he will make all of the correct decisions, but he is also centralizing a big portion of the decision making. That can be good, especially if he is of the PBFD variety.
> "Do we absolutely need discount functionality at launch?"
This is a good question to have. You want to only build the MVP. But if you don't know what it will take to build[1], then you can't make that decision. If you make that decision, and don't communicate to the team that you made that decision, and they build a product that needs to be completely redone once that feature needs to be done, that's not ideal.
> "Which tasks depend on which other tasks?"
This is a good question to have. Another good question is: What parts of these tasks can we work on even if the entire story is dependent on some other task? Is the entire job going to take at minimum 23 weeks, or can we on week 1 spend a bunch of time doing "product cart price calculation" spike engineering task, while at the same time doing a "shopping cart containing product" spike task. Then when we get to the story, suddenly the implementation of the entire pipeline can be completed in a single sprint. If your engineers only see the story when its popped off of the top of the backlog, they won't be able to accomplish that.
This guy must be on another astral plane :-) Who is the customer ? Ahhhhh the one who pays ! For a second I thought he meant "users" ! :-)
* Use static types
* Use CI and version control
* Use schema-based data storage
* Prefer function calls to events
* Use formal verification if possible
etc.
> And is it always applicable?
No heuristic is always applicable.
Exactly. That's why it is called a heuristic and not a rule. :)
Great idea until it isn't. The article is full of bullshit but one thing is very true. We can't predict the future, especially so when we deal with humans and society where stuff changes fast. Strict schemas are more pain than gain here.
> * Use formal verification if possible
Wonder when F* and the like get mainstream so that "if possible" becomes "almost always".
A healthy practice combines both depending on the nature of the task.
> 7. … You cannot improve a system by tinkering with the parts.
This last statement seems to apply more to factories or construction sites, not software engineering. Obviously systems can be improved by tinkering with parts that are shared and actively used by multiple systems.
> You cannot change anything without changing everything. You cannot improve a system by tinkering with the parts.
Those sentences seem to outright contradict each other...
In my experience, this is true mostly for planning and control. It's important to remember the goal when building something, but at some point you need to focus on the output as well. "a focus on outcomes only doesn't yield any output"
That's about the only soundbyte I liked from this list; but, on the plus side, I did like that soundbyte quite a lot!
Ha, I wish that were the case. Everyone wants a date and gets upset when the deadline is missed.