What helped me the most in programming and design was to shift my thinking away from trying to create a complete (or “perfect”) product right from the start and towards creating a minimal product with the most essential feature set first and iterating from there. I guess this is what the author wanted to point out.
It helps me to avoid getting overwhelmed with complexity and, as a nice side-effect, to avoid premature abstraction and optimization. Most of all, it helps me (as mentioned in the article) to actually build something. It is also quite satisfying and motivating to quickly get to a state where your product already works and to build on top of that, making something better that already works.
I used to work like that when I began programming, because I just wanted to solve a problem for myself and put it out there as quickly as possible. I had to re-learn this way of thinking as my ambitions grew and as I wanted to make things “perfect” and be “professional”.
Of course, in this approach lies the danger of accumulating features and complexity, so it is important to keep the focus on the problem or the “essence” of what the product is supposed to be.
"One group is instructed to submit 100 photos over the quarter and the other group is instructed to submit one perfect photo.
The group that is instructed to submit 100 photos gets better because they start right away and start taking photos and learn about composition. While the other group doesn't get better because they hem and haw over what a perfect photo is."
If true, I would want a refund if placed in the latter group.
Ironically, this is also the downfall of most "agile" practicing dev teams. They've adopted scrum, they've adopted all the overhead of Jira and 2 week sprints that they never rethink, but nothing gets shipped unless it's perfect, and so nothing gets iterated on, nothing progresses, no evaluation of the work ever actually feeds back into a positive reinforcement cycle, and so you just get waterfall with much more agony.
In my last company, we were trying to ship refactors and improvements at the same time, and it inevitably broke down horribly when we'd discover some requirement that had originally never been documented or built in some component. So the scope for shipping would change from a one-to-one refactor with incremental iteration in subsequent sprints, to many cycles of QA and fixes before even minor design improvements could be shipped.
It's characteristic of every dev team I've been on that's tried to use off-the-shelf agile practices, because there's no risk tolerance at any level higher than IC. Everyone's afraid of how they'll appear, and nobody trusts anyone lower than them on the org-chart.
I might have read it wrong, but I read OP as saying something like "people want to do agile, but wait until the project is perfect, thereby negating the whole point".
Like the sibling comment here, I've seen this plenty of times too. Not on "most projects" or "most places", but certainly on most spectacular failures I've witnessed.
I don't think the one who's seen "hundreds" of examples could have done so without being an "Agile coach" or something, maybe a temporary contractor at most, either way getting a pretty arms-length look at how a team is operating or is starting to adopt a new procedure.
Not so much the overall project, but definitely the smaller components within an ongoing project. Probably should have specified that because I'm almost always working on an established thing, rather than a greenfield thing.
> nothing gets shipped unless it's perfect, and so nothing gets iterated on…
That’s why a solid, painless, quick rollback story is absolutely vital but underrated for agility. It’s not a big deal if you ship a regression but can roll back quickly. On the other hand, if every release is playing for keeps, you’ll slow down to a glacial pace to try to ship perfection. But perfection is impossible no matter how much process you put in front of it—you will ship a bug some day. So pretending like you can’t ship bugs because you have initial design reviews, multiple code reviews, sign-offs from multiple stakeholders, CI that takes 3 days to run, etc. just makes the day you do ship a big that much more painful.
The issue is that big messes can be made that are hard to clean up in one small release.
For example, one of our teams had the requirement "Allow end users to programmatically configure widget xyz". Now, widget xyz has a janky design and a table with 50 columns associated with it.
So what did this team do? They took that internal table definition, made a CRUD api that exposes the whole thing, and moved on.
Tell me, how do you fix something like that like that? They followed the agile route, got an MVP out with hardly any effort on their part. But now we have this API that shows off 20 years of legacy that our end users now depend on.
And to be clear, of those 50 fields, maybe 3 of them mattered to the end user and the rest could have been inferred. But doing that inference is a lot more work as it takes understanding the domain.
> Tell me, how do you fix something like that like that?
A little at a time; continuous refactoring/improvement is a vital pillar of agile. You've got 50 redundant fields that can be inferred but you have to understand the domain to do that? Well, understand the domain a bit, and infer one of them. Then next time you come back to that part of the code do another one.
(I mean, if the table was like that already then it sounds like the API didn't introduce a new problem, it just surfaced a problem you already had)
> continuous refactoring/improvement is a vital pillar of agile.
The problem with this pillar is it's often viewed as nothing more than waste by business. Try arguing with a PM "Hey, we need to actually take a bit of time to redo XYZ because it's really janky" and they'll come back with "Yes, but client PDQ is ready to give us money for this shiny new feature! We don't have time to waste redoing XYZ because it's not currently causing us any problems".
The table going from 1, 2, 10, 20, 50 columns never actually hurt the system. It got nasty looking but ultimately not something you could sell to a manager "Hey, we should address this". So, by the time "Hey, let's expose this" rolled around the institutional will to want to correct anything had long since past.
It's really easy to sell redoing something if it's actively causing harm to the systems, but stuff that's just a bit janky has next to 0 priority (often even negative priority because fixing it might break something).
There's a balance to be had - and frankly most code has a finite lifetime and developers often put too much priority on making it cleaner than it needs to be. The technical debt metaphor is a good one; a PM should understand that when code isn't clean it increases the cost of making changes to that code, and sometimes that's a price you want to pay and sometimes you don't.
Well I suppose that's the difference between thoughtful systems and process and zero systems and process, and also poor problem definition. There is some nuance between "ship literally anything to end users" and "ship an improvement" or something else to end users, or to a beta that roles out to end users and isolates the possible regression to a smaller surface area. It also seems like those developers might either suck (possible, but uncharitable), or that the system rewards the wrong things.
But much of the time, better or worse laters of bureaucracy in the system come about from these mistakes which will eventually happen, so it's a very valid point, and I do think a lot of the time it's companies building up scar tissue and not being capable of getting the necessary surgery to fix it.
> It also seems like those developers might either suck (possible, but uncharitable), or that the system rewards the wrong things.
Yes, they do, but also it's an entire department problem and one that the upper bureaucracy doesn't see as an issue. I'm really not surprised this was the route that particular department took. Office politics are fun, though, so sucking at your job often doesn't mean anything if your managers are all buddies.
But before the creation/evolution of that department we already had these sorts of problems. This may just be a "just my company" problem but I don't think it is. After all, from what I know of business management, this sort of "extra staff and rework is waste" mentality seems really pervasive.
Yep, that all sounds quite familiar, definitely not just your company, it's characteristic of trying to monkey-patch whatever management can point a finger at, because that's what they're rewarded for, and that's what their manager is rewarded for.
No word of a lie, I ran into a colleague from the first company I saw this problem at (and was fired from) years later when I happened to revisit a restaurant I liked in the area. I asked him if he still worked there, and he laughed. Said that they eventually fired the entire department and he stayed on just as a consultant for a bit. Which is odd, because although I was a naive early-twenties kid at the time, I could tell everyone else in that department was quite good at their jobs.
> "Allow end users to programmatically configure widget xyz"
That's an extremely poorly defined requirement, and I would say that's the ultimate source of the issue. Your team took that and made a crud api. Another team might have written a YAML based DSL. Another team might have created an even more complex scheme.
A BA/PM should have pushed back on that and gotten much, much better specificity as to what the users needed to do.
> And to be clear, of those 50 fields, maybe 3 of them mattered to the end user and the rest could have been inferred. But doing that inference is a lot more work as it takes understanding the domain.
Exactly -- except the part about "doing that inference is a lot more work". Compared to recovering from the wrong path the software has taken?
> For example, one of our teams had the requirement "Allow end users to programmatically configure widget xyz". Now, widget xyz has a janky design and a table with 50 columns associated with it.
> So what did this team do? They took that internal table definition, made a CRUD api that exposes the whole thing, and moved on.
> Tell me, how do you fix something like that like that?
That's genius! You can now use your metrics from that API to determine how the users are actually using it to provide more value.
Are they hooking into something they shouldn't? Well then they are missing a feature and that is an opportunity for you to build that feature for them.
I think "The Problem with Agile," especially at this point, is mostly upstream of any implementation details.
What kind of an organisation is going to adopt a packaged management method like that? Cargo cult adoption of practices, language, job titles, consultants, tools and formal certifications... The company that invented agile would never have "gone agile" in 2023.
I'm not saying that agile can't work. I'm saying that an insurance company "adopting agile" is an insurance company buying a trendy management method for their engineers. It matters not if the method is called agile or a 1972 booklet from the USSR. Practices, practiced blindly are rituals.
When the users/buyers of software don't actually want (sometimes for legal reasons!) agile development, then shoehorning them in results in what you describe?
The photography version is the original. It was retold as ceramics in the book 'Art & Fear', because the authors (who were photographers themselves) were trying to appeal to a broader range of artists.
If one group submitted 100 photos and the other group submitted only one, I’d argue that the first group was simply given 99 more chances to impress their professor.
Apparently the "ceramics class" story that you see all over the place after it appeared in the book "Art and Fear" was a modification of this real story, retold in a closer-to-original form in "Atomic Habits."
The Art and Fear authors credit Uelsmann himself as the source of the story; whether I believe he really did it with actual students for a whole semester, on the other hand...
It's a little bit of a "just so" story in any form, though the lesson of repetition is fine regardless of its literal truth.
That old chestnut? If told that and I was in the "other group" I would pipe up and say "only one way to do this, submit 100 photos to me ASAP and I will pick the best one.
The way I try and address this is by basically turning off my inhibitions on my first pass of anything. Literally just start spewing stuff, whether its code or writing a tweet or blog post, making a presentation, etc. Then my second pass is with a much more critical eye and I start editing or reworking big chunks.
"also don't ever give someone an unsolicited code review on Twitter. It's rude."
I'd personally welcome people's free code review, on any platform, when clearly the code "wasn't perfect". I don't see why someone would take offence from free advice, unless it was condescending. You're always free to ignore it. Eitherway, you won't excel in any topic without feedback.
Sending an email directly may be welcome. Commenting on PR (if open source) is also probably welcome in most circumstances.
It's the difference between pointing at an ESL speaker and saying they talk funny in a group social situation, versus pulling them aside and letting them know they're using some words wrong.
Some people are OK with being publicly called out, but more people will feel like they're being given constructive feedback rather than publicly called out if you talk to them directly
People on Twitter just want to broadcast their opinion and get affirmation, they don't react well to attempts at dialog. It's all just attacks and counter attacks these days.
I disagree. Unsolicited feedback lacks context and might not be intended to help the developer. Feedback to someone you don't know should be offered only if they're explicitly asking for it.
I think there are platforms for both. If you don't want feed back you can publish a blog that doesn't allow comments. If you publish on social media you are inviting social input.
Sometimes people want the participation and attention that exists on social media without the reason that attention exists.
Of course, advice should always be kind. And allow people to ignore you if they want; this includes not "piling-on" and restating a criticism that has been said by others.
Suppose you were 60 years old with 3 kids who live out of the house. You like to go golfing on the weekends, and have no intentions of ever going pro. This weekend, you get to the golf course to see a series of robots have been installed on the course. When you swing, they always give constructive, helpful feedback to try to improve your golf swing. You cannot turn the robots advice off.
I would feel horribly patronized in this scenario. I don't go golfing to get better at it, I go golfing to relax. Similarly someone can program and not necessarily want to be better at it. It depends on their goals and desires. Giving someone advice before asking means you have to guess at what their goal even is. In many contexts (work) this is fine but in general it is not.
To answer your question, the reason why someone might reasonably take offense to unsolicited advice is that unsolicited advice is inherently condescending because it implies that the advisor knows more about the topic than the advisee. It also implies that the advisor knows the advisees skill level and goals. It's kinda insulting, and in another way it's almost controlling as the advisor reframes the discussion around "being good at X". I don't want to be good at golf, I want to enjoy my time golfing.
I completely don’t agree about your analysis of what givers of advice might feel like. Some people just want to share what little they know in the hopes that others return the favour.
Let’s say you are installing bike seats for your kid, but you attach it in a way that 3 minutes into the ride your child would fall off. A neighbour sees this and comes over, unasked, to tell you you did the straps wrong. Are you now insulted or glad someone taught you something important?
In general the problem about people who feel insulted about things is that it is their own interpretation. Insult lives with yourself. You can choose not to be. Why would you put so much power into other people’s hands?
Don’t get me wrong, I can get insulted, so it is a constant work in progress.
I feel like in your story instead of robots, people would be more like receiving unsolicited advice. A machine is a machine. If you get offended by advice from machines you have totally different problems.
Not necessarily. I might receive an unsolicited offer to have my windows washed by a guy at the lights. I welcome it because my windscreen is dirty, and I give him $5.
Just build it is the best advice for personal projects. Because, generally speaking, we only have a gist of what we want and only through building, do we discover how to actually build it.
It also means it doesn't forever sit in the perfecting stage, and perfection is infinity.
I agree. For months, I wanted to ditch Bootstrap from my blog theme and implement all the CSS from scratch. But the idea of making a "perfect" theme was daunting. Then, at some point, I just decided to go for it and publish my very incomplete WIP theme anyway. Working on it "live" has been liberating and, honestly, more fun than expected.
I'm not a designer but why the blog post & linked redesigned homepage font feels off?
I don't know what I dislike about it. HN font seems better to read. About the homepage:
- Is it all the excess space around the text?
- Is it that "Work Highlights" isn't aligned with anything?
- Is it the background switching that makes feel in 1 case there is a different font or font weight?
- Actually there is 3 background colors and in 1 case the font is even different color: white.
- The "Currently" feels a different font size than anything else. Actually it feels a different font for me.
- And it is not the same color as previous headers.
- The bullet points feel stuffed... or I don't know... the text above is different line height. Or maybe the excess space (doesn't fill the image height)?
I don't know what's right or wrong. Maybe I just like consistency :)
Sorry for the unsolicited part, it's more like I want to learn more myself :)
Seth Godin tells something similar about writing of Issac Asimov[0]
" Isaac worked with me when I was 24 years old. He wrote and published 400 books. I was sitting in his living room in Lincoln Center in New York City, and I said, “Isaac” — being presumptuous — “how do you go about writing 400 books?” He said, “Here’s the secret.” He pointed to this old manual typewriter. He said, “Every morning, I sit in front of this typewriter at 7:00 am, and I type until noon. It doesn’t have to be good, but I have to keep typing.”
In "So Long and Thanks for All the Fish", there's a forward Douglas Adams wrote for a book by another author which was unfinished. He related two stories: the first about an ancient Greek poet who would spend the morning reciting verse, which one of his disciples would write down; then he'd spend the afternoon throwing the vast majority of it away. The second was about another author who'd type out a page of a novel and stick it on his wall near the bottom; every so often he'd page off the wall, type in an improved version, and put it on the wall a little higher, until all the pages were at the top.
His point (speaking about the other author) was that the book was "unfinished" both in the sense of incomplete, but also "unfinished" in the sense of unpolished; it was a warning that the quality of the writing would not be the quality the readers were used to from that author.
(Which was apropos to include in "So Long and Thanks for All the Fish", since it was also a novel started by Adams and not "finished", in either sense.)
It's a hard thing to do, to just sit and write something you feel is garbage. I think I've mostly managed to get to the point where I can do it for coding, but not really for text yet.
This is why when people ask me the best way to build an app, I tell them to pick an idea they're excited about, and learn by building it. Then, be prepared to throw out the first version and try again based on what they've learned.
So much advice out there on the internet is really not meant to help you – it's to sell you on content or tools. The best way to learn is by building.
Most of the technology choices you make will be marginal. There are incredibly profitable startups built on PHP. Until you go through the process and see for yourself what a particular approach yields, you won't truly understand it no matter how many books or articles you read.
A lot of coding work, and modern work generally is all learning. IE, a lot of tasks consist mostly of learning to complete the task. There's just a lot of cascade. The language, library, codebase, prerequisites specific to the task, etc.
Often you spend half the day learning about the task, then learn or refresh some bit of required technique or knowledge... then you just do it.
In carpentry, engine restoration, cooking or whatnot... this is typical of early days. Every early carpentry project requires some learning. A new cut, a join or glueing method. As you mature in the discipline, the density of novelty and learning decreases.
"Learning" is a bit of a catch all. Learning about the product, library or API might just be literal information gathering. Other "learning" might be skill building, requiring practice and repetition to "learn." EG, brushing up on regex to deal with some misbehaving code.
In any case, we tend to be pretty resistant to openly practicing, or training ourselves. We prefer to err on the "knowledge gathering" side. Or... we do agree to practice, but adopt a low effort "just practice" mentality that isn't effective. Layer these tendencies onto modern work, where the divide between learning and doing is unintuitive and vague... most of us are not practicing enough to do what we want to do.
"Just build" is, IMO, mostly a hack to make us practice with sufficient effort and persistence for learning to happen. If you have a thing you want to build, you need to practice building it. The proficiency you acquire is often more useful and valuable (even for the task itself) then the concrete output... until a much later stage in the game than we intuit.
Having done a recent refactor + redesign of my personal website, I echo with this sentiment. It's much easier to go live sooner and do incremental improvements than launch everything all at once.
It helps me to avoid getting overwhelmed with complexity and, as a nice side-effect, to avoid premature abstraction and optimization. Most of all, it helps me (as mentioned in the article) to actually build something. It is also quite satisfying and motivating to quickly get to a state where your product already works and to build on top of that, making something better that already works.
I used to work like that when I began programming, because I just wanted to solve a problem for myself and put it out there as quickly as possible. I had to re-learn this way of thinking as my ambitions grew and as I wanted to make things “perfect” and be “professional”.
Of course, in this approach lies the danger of accumulating features and complexity, so it is important to keep the focus on the problem or the “essence” of what the product is supposed to be.