At the time of writing this, this "article" is #1 on HN default sort. It's an incredibly short, and fluffy post (self reported as a 3 minute read), with little more substance than an urban dictionary listing. I'm baffled.
On the topic of yak shaving though: I recently felt like I wanted to do more technical writing. The prerequisites of this idea involved building a static site generator and redesigning my website. While building the SSG, I of course imagined all the features that would be expected, a tagging system, JSON output in addition to markdown rendering, custom syntax highlighting for codeblocks etc etc. I had that idea at least 1-2 years ago, and I've only recently written my first post within the past 2 months. I think I enjoy tinkering with build systems much more than writing.
I think we are many who read hacker news for the comments.
The downside is, it’s not so much the article that becomes relevant, but the topic. HN felt like talking about yak shaving and all we needed to get started (you included!) was a headline.
It also creates a vicious cycle where people who do care about article quality are more likely to disengage with the site -- and these are most likely the people who write the highest value comments.
I don't think a culture of 'only reading the comments' is at all a good thing.
Agreed - it's like watching the emergent complex behavior that an AI spits out after you give it something unique. You're curious - what on earth could the HN crowd have to say Yak Shaving? The input doesn't matter at that point to a degree, it's the unique/novel thing that was outputted.
Agree, though HN also clearly has the “Ask/Tell HN” if someone feels like taking about something and they’re by default down weighted vote wise, which to me says the posts linking to content should have substance.
For the people that read HN but don’t comment, please load/scan a link before upvoting. Not doing so will have a net negative impact on HN if enough people are not checking the links.
> The prerequisites of this idea involved building a static site generator and redesigning my website
To clarify: that is not yak shaving, that is just plain old procrastination. Yak shaving includes tasks that you have to complete in order to do whatever your original intent was. For example:
* I want to add new feature to my code.
* The feature requires a database migration.
* To apply the migration to test environment I need to set up AWS credentials.
* To set up credentials I need to log in to AWS console.
* My password hasn't been rotated in a while so I need to update it.
* etc
> Yak shaving includes tasks that you have to complete in order to do whatever your original intent was.
The example (and definition) in the actual article disagree with you:
"You want to bake an apple pie, so you head to the kitchen.
In the hallway, you notice some paint chipping on the wall.
So you walk to the hardware store for some paint."
You obviously don't need to deal with the paint chipping before baking an apple pie.
Wikitionary gives both definitions: a blocking task or a procrastination detour
Similar thought: I think you could stay there's a spectrum of yak shaving. I wouldn't as the article call 'going down the rabbit hole' yak shaving as rabbit holes feel more intentional.
My feeling of things related to yak shaving:
Rabbit holes - intentionally following some thread of associations looking for some insight or unexpected solution
Yak shaving - While working on something important you iteratively find something more important that you feel you need to deal with first. Supposedly but not necessarily it's something you have to deal with to be able to solve the original problem.
I agree that the articles example of yak shaving is a special case of yak shaving where it isn't very clear that the shaver feels that the distraction is more important. But I suppose such feeling is always a bit implied in the word distraction.
If you want to write and for it to be a habit you can reduce the friction of writing.
Create a GitHub repository and create a journal repository and create a markdown heading for each entry. It works.
I'm on 4 pages of 100+ journal entries each. See my profile, I journal computer ideas, algorithms in the open.
Using WordPress or using complicated software shall take time away from writing regularly. And you need to open a document and write, not abandon your blog due to forgetting how to post
> I had that idea at least 1-2 years ago, and I've only recently written my first post within the past 2 months. I think I enjoy tinkering with build systems much more than writing.
This is very much an easy trap to fall into! What helped me was not sweating over the small stuff and setting up an instance of Grav, though I think that most of the turnkey blogging solutions out there would work (e.g. Ghost/Bolt as well, maybe not self-hosted Wordpress as a first option due to large surface area): https://getgrav.org/
What I really like about that solution in particular is that it is flat-file based and also has an admin web dashboard that's a separate plugin that can be enabled/disabled (some might prefer writing text files directly, with front matter and all) and has separate URL path that can be put behind basicauth (in addition to built in auth), client certificate auth or anything else.
It's not perfect, of course, and has given me the occasional headaches, but it's also good enough for my blog: https://blog.kronis.dev/
That said, I still struggle with my homepage - instead of going back through 5+ years of projects and describing all of the noteworthy ones, putting up a few galleries of screenshots, listing technologies, ordering them by relevance and also making sure that it doesn't contain too much data... it's just sitting there, on my TODO list. It's been that way for a while now.
The HN new queue is interesting because you often have a sea of articles with absolutely no votes, and then one or two articles with dozens of votes. While votes are probably power law or exponentially distributed, that skew seems a bit too extreme.
When quasi-blogspam articles like this rise to the top so quickly, one has to wonder whether it’s the result of vote manipulation.
Yes, been there, done that: tinkering (or yak shaving) makes it easy to forget about KISS. And sometimes results in too many open tabs in one's browsers ;-0
But even the best of us are prone to fall for it, and sometimes they even produce excellent results, cf. Donald Knuth and the TeX / Metafont ecosystem:
Between 1977 and 1979 computer scientist Donald E. Knuth of Stanford University created the TeX page-formatting language and the Metafont character shape specification language, originally as a way of improving the typography of his own publications. [...] -- https://historyofinformation.com/detail.php?id=3339
My experience is that programmers always try to make things as simple as possible, and when they fail at that, it's because they don't know how, or don't have enough time, or maybe the "simple" solution isn't persuasive enough that it covers all the cases, so a "more complex" version is preferred, or something like that; not because they forgot "whoops" I was supposed to make things simple not complicated.
The only times I have heard "KISS" suggested in earnest have been from bad managers.
> But even the best of us are prone to fall for it, and sometimes they even produce excellent results, cf. Donald Knuth and the TeX / Metafont ecosystem:
I don't see how this has anything to do with failing to keeping things simple, yak shaving for sure, but this yak (if it's a yak) did need the shave: there weren't any typesetting systems comparable to TeX at the time (and by some opinions there still aren't). What else can you do? Have someone spend hours typesetting and resetting a thousand page book every time there's an error, or turn the job over to a computer and automatically typeset it?
This is just solving problems. Solving problems you have is good, and where people go wrong, it's when they are solving problems they don't have (but perhaps think they might), or perhaps they underestimate how much of their problem the computer could actually solve.
Emergence at work. There is much to be learned from just the behavior externals of HN.
Uniqueness, mystery, narratives and humor/silliness are probably big drivers of attention on forums and news sites. Like the other commenter suggested, the gold is typically in the comments. I don’t have data to back up this assertion, but it would make for a good study/article.
>At the time of writing this, this "article" is #1 on HN default sort. It's an incredibly short, and fluffy post (self reported as a 3 minute read), with little more substance than an urban dictionary listing. I'm baffled.
That’s not the definition of yak shaving I’ve ever used. I’ve always thought of it more like:
- I find a bug
- I track it down to a library I’m using. The fix is in a later release.
- I go to upgrade the library, but that brings in some transitive dependency upgrades that accidentally broke an API used elsewhere.
So now instead of fixing my bug I’m rewriting API call sites across my project.
I think my understanding of yak-shaving was more, can't get to the thing you were trying to do because of cascading blockers. Less distraction, and more unknown scope and complexity.
I quite like the Malcolm in the Middle[0] example of yak-shaving, though it's a combination of both blockers and distraction.
My understanding of yak shaving is that if you need to create a system for selling ads then you'll start by developing a graph layout algorithm that produces a set of optimal layouts for routing power in a data center (because you don't want to be called out if your system doesn't scale.)
That's a much more correct example than the one in the article. The "real-world example" in the article describes doing something completely different than intended, not out of necessity but by distraction.
> yak shaving - Any seemingly pointless activity which is actually necessary to solve a problem which solves a problem which, several levels of recursion later, solves the real problem you're working on.
The other side I see to this is that if I don’t refactor this code, who will?
I guess that opens the debate to does the code actually need to be refactored? Sometimes not, but I have a very hard time leaving a 2000 line function alone, or a class with many levels of unnecessary inheritance.
What I’ve started to think is that there are people who get things done, and people who refactor.
People who get things done ship code fast. The good ones know when to make trade offs of purity vs practicality. The bad ones write unmaintainable code. They tend to view programming as a job, and code quality as a burden. They may refactor and make unrelated improvements, but it’s uncommon.
People who refactor still get things done, but most of their work have rabbit holes tacked on. They delivered a bug fix, but they also greatly improved the test suite and tooling. They tend to value purity, best practices, and might view programming as a craft/art. The good refactorers make the high value changes that are a net benefit to the team; they might care about cleaning up important parts of the code, improving developer experience, or adding test coverage to critical functions. The bad refactorers rewrite a bunch of code because it wasn’t pure, and the team, customers, and business have no observable effect from it.
I think teams need both kinds of people on it. Too many doers will lead to fast progress at first, but eventually grind to a haunt. I felt this was a HUGE problem at my team in AWS, and a major factor of why I left.
Too many refactorers is equally problematic. Your code will be of great quality, but velocity will be unacceptable for the business.
I personally am a refactorer. probably more of a bad refactorer than good, but it’s something I’m working on.
Maybe this is a rationalization for my behavior so that I believe it’s important, but my time at AWS shipping 3 features a year with a team of 16 says that code quality really does matter.
What you're saying and what the article is saying are two different things. The whole point of the article is not "Don't refactor code"; it's "Never fix a bug and refactor in the same pull request".
Building on this, I see a lot of areas of code that are effectively untouchable because of how much energy would need to be invested to understand the code and its context before making a change. So if a change has to be made to fix a bug or add a required feature, it's done in the most low-impact way, which only makes the code that much harder to understand in the future.
Meanwhile, I can't get refactor-only commits through because nobody wants the code to be touched unless absolutely necessary.
We're in the middle of migrating a massive PHP codebase to Java. The code I'm talking about is newer Java code. In a few years, people will be wondering why the Java code is as much as a mess as the PHP code and, if I happen to still be around, my response will effectively be "I told you so" (in kinder, more productive terms).
I've basically determined that my only option to ensure continued or improving code quality is to combine refactoring and bug fixes in the same merge request, while still keeping them in separate commits. That way whenever I touch a part of code for bug fixing or whatever else, I leave it behind in much better state than it was before.
> I've basically determined that my only option to ensure continued or improving code quality is to combine refactoring and bug fixes in the same merge request, while still keeping them in separate commits. That way whenever I touch a part of code for bug fixing or whatever else, I leave it behind in much better state than it was before.
I agree, in practice I think this is the best option, with some kind of timebox for the improvements made.
One thing I'd like to add is setting up some kinds of tests. If nothing else is available, E2E tests for the critical paths of the business are a good start. For (micro)services, getting API contract tests to work is also invaluable.
Refactoring while bug fixing can be good. But depending on your metrics, it might be underappreciated and seen as time wasting.
The guy the goes around blasting bugs like there's no tomorrow looks good to the boss. When he leaves someone will have to refactor his mess and that's wasting time again.
I have had this conversation yesterday, and the refactorer asked this very question. Here's my answer:
The question is improperly formulated. With your behavioral patterns of immediate refactoring, the question seems to be: "if I don't refactor this code NOW, who will?".
I'd say that if you don't refactor the code now, someone else, maybe future you, may refactor it later.
Most sane companies will protect engineering from impulsive feature requests and will add them to the backlog for future consideration.
I'm trying to instill the same protective mindset in my teams, and help them not do refactorings immediately but rather consider them as potential work as dedicated items in the sprints or so.
Doing so, prioritizing becomes a natural part of the refactoring/tech debt/tech risks agenda, because we have an overview of the work to do globally.
In my experience (three years, two companies, so not much) refactors are beyond last place for prioritization. Even my current company which does a great job of handling tech debt doesn’t track refactoring well. How would you even do it? Imagine how many tickets you would have about the things that need to be improved.
I guess this is delving into queue theory and how the work queue is growing to infinity because there aren’t enough workers.
Personably I just allocate X% of my time to this kind of work and spend it on the most productive improvements. You don’t have to die on every hill you see. And if most people do this it results in a constant shift to something better while still achieving business goals.
I tend to think of yak shaving as the annoying but _necessary_ activity of fixing things you need to fix to close your bug. Not frivolous refactors. More like adding decent logging to a complex system, cause otherwise, how will you know why your feature doesn’t work?
Yes the example is wrong. It’s about making an apple pie, but figuring out you have no apples, so then you’re going to the supermarket etc etc.
It’s about “necessary” things to achieve a goal, without appropriately weighing costs vs benefits nor considering alternative solutions (perhaps making a chocolate pie instead).
Exactly, what is mocked as Yak Shaving is the important stuff. But try telling your non technical manager why you need to add that logging system, which requires its own testing and deployment.
In this scenario you are the one focused, the non-technical people that shuffle tasks around playing 'agile' are the handicap. It could take a couple of hours or a couple of days to get that logging done but explaining to the non technical manager (who refuses to learn) why this needs to be done is a task in itself that cannot be underestimated.
Me too. Where I work it's slogging through the process of doing just about anything. A simple task ends up being a to do list that's 10 items long. There's a 60 day use it or lose it policy on just about everything so you may find you need to completely rebuild the dev and testing environments which include automated as well as complicated manual processes before you can even begin to fix the bug.
“ Never fix a bug and refactor in the same pull request.”
I’m sorry, but this is backwards. Bugs are many times caused by badly written code and you can tell when it’s the case. Refactoring the code many times fixes the issue without ever having to figure out where the needle was in the haystack.
I guess in every field there are platitudes and prescriptions. At the end of the day, I try to follow first principles and ignore them and just focus on building a great product.
What I see in this article is a disregard for the costs associated with context switching. My argument is, if you think you can handle the rabbit hole, and you think those related tasks will need to be done anyway at some point, head off to Wonderland. Because you have the context of the situation fresh in your temporary memory, so you’ll get it done faster than if you switch contexts and come back later.
It also misses the point that sometimes refactoring makes it _easier_ to fix the bug, and that a large part of fixing a bug is understanding exactly what's happening with the code, which refactoring can also make easier.
Overall I disagree with this article, both in it's definition of yak shaving (as being unrelated to what you're doing), and in it's assertion to never refactor and fix a bug in the same PR (now I'm not saying you should refactor things every time you fix a bug of course).
I'm going to throw an addendum on to this one: if you fix a bug, and then do a refactor, I'll agree, it's probably best to split the PR's up. But that's just the common sense of keeping changes small and logically contained. I'll also agree that it's best not to interweave the two.
Refactors usually take much longer than the bug fix, and while it acrues technical debt, there may be more urgent things to take care of. The article is about focusing on your initial goal, and then filing the refactor as a next step action item, instead of just growing scope endlessly.
I understand where you’re coming from. I would argue that if the amount of refactoring required to make the bug clear takes that much longer, then all the more reason it should be prioritized. This is really the purest definition of tech debt, because there may be other bugs present in the code you are unaware of. This is assuming no tests cover the bug, because if they did, it wouldn’t have made it into production. Honestly you should be doing it all, because you have to understand the full scope of the issue to properly fix the bug, test it to prevent regression, and in order to test it it must be testable. So I would say if there are no tests, and it is not testable code, the least amount of refactoring you should do is make it testable. You actually don’t even have to write the test if you really want to cut corners. Just through single responsibility principle, dependency injection, and writing code that could be tested is enough to bring it 90% the way there. You can even break the dependencies and theoretically as long as you don’t violate the interface the functions you refactored should hold up. The simpler and more broken down the code is, it gets to the point where you say, this function has one if statement and two return statements, writing a test is actually redundant compared to the code. If it’s not mission critical code, you can really cut corners, if you’re in a hurry…
I think it should be more like, try to separate "formatting" and other changes into separate commits instead, you know like ones that change the whitespace all around, and other layout stuff, so diffs of the actual fix are easier later.
I find it slightly insidious how the entire concept of yak shaving is framed in the article as a lack of attention span or directed focus on the part of the developer, instead of a consequence of being required to work in a suboptimal environment. In my experience the majority of yak shaving is spent removing direct impediments to solving the task at hand. Distraction is always an issue, but I feel that falls under the bracket of "doing the wrong task" rather than "the path to complete the task is indirect and convoluted".
With this kind of framing we can look at the cause of yak shaving as a failing of an individual, rather than a lack of an accurate and holistic view of what the task entails given the current state of the system.
https://projects.csail.mit.edu/gsb/old-archive/gsb-archive/g... The OG only specifies that it's "related" to the task, and makes it pretty clear that one could come up with a significantly cleaner path to the original goal - Yak Shaving overlaps heavily with "flimsy rationalization"
Many times I've found myself in situations like 'yak shaving'. To do this I first have to do that, and to do that I have to do some other thing, thus falling into a never ending stream of tasks that make me lose focus of my original goal. It seems to me something very common while performing unexpectedly complex jobs.
My point however is not to discuss this. What bothers me, and only a little, is the label chosen to describe situations such as these. Why 'yak shaving' and not something else?
I mean, the Ren & Stimpy connection is meaningful for the author, and that's ok. But if every time I want to refer to it I have to explain why it's named as such, or even explain who Ren & Stimpy are, maybe I'll be better served by some other, perhaps more appropriate label.
Calling it 'Going down the rabbit hole' is no doubt better, at least to me, but not completely. This expression captures a different mood, namely that of finding ever more connections in an endless stream that does not necessarily make me forget my original goal. For instance, while writing a paper, many times I find myself going down the rabbit hole, ending up with these monstrous footnotes that try to record how deep that rabbit hole goes. But when that is done, I go back to the main topic and move on.
So what could I call it other than 'yak shaving' or 'going down the rabbit hole'? I'm open to suggestions.
> Calling it 'Going down the rabbit hole' is no doubt better
It may be more recognisable, but I wouldn’t say it’s better. The metaphor of going down the rabbit hole has you go deeper into the same subject while yak shaving has you go into increasingly tangential tasks to the point an external observer wouldn’t recognise your primary goal.
In other words: the longer you spend going into the rabbit hole, the more you familiarise yourself with the matter; but the longer you spend yak shaving, the farther away you are from finishing the original task. Yak shaving is antithetical to going down the rabbit hole.
This person has obviously never been in a situation where to get the data to fix the bug you need to modify the instrumentation, which requires a new data format because you are the first to use dicts of dicts of floats, and when adding that you end up with a random seg fault, so you debug that and find out that the stack frame pointers disappeared last week when GCC was upgraded by a vendor patch on your colleague's laptop, but not yours, and so he checked in a "temporary" fix for that. Frame pointers restored, you find an off by one in the serialization of floats which you fix. So you go to collect your data but the data aggregation system, which said it supports your data type in fact does not in the current version, so you upgrade it, but for that you need a different GCC update. But that GCC needs a different libstdc++ which causes compile errors in your app. So you find yourself in the Makefile adding a way to use a local copy of libstdc++, and you can't remember why you were even fixing the bug, because in the meantime the docker image used for the mock database has been updated, adding a new bug that masks the bug you were supposed to be solving (but you won't find out about that for 3 more months).
Your scrum update for 6 days running is "maybe tomorrow", and your cat runs away because you are so preoccupied with the bug you forgot to feed it, and your yak needs shaving because in a daze on the way home from another day wasting your life at this stupid job, you forgot to pick up razors.
On the topic of yak shaving though: I recently felt like I wanted to do more technical writing. The prerequisites of this idea involved building a static site generator and redesigning my website. While building the SSG, I of course imagined all the features that would be expected, a tagging system, JSON output in addition to markdown rendering, custom syntax highlighting for codeblocks etc etc. I had that idea at least 1-2 years ago, and I've only recently written my first post within the past 2 months. I think I enjoy tinkering with build systems much more than writing.
The downside is, it’s not so much the article that becomes relevant, but the topic. HN felt like talking about yak shaving and all we needed to get started (you included!) was a headline.
I don't think a culture of 'only reading the comments' is at all a good thing.
For the people that read HN but don’t comment, please load/scan a link before upvoting. Not doing so will have a net negative impact on HN if enough people are not checking the links.
To clarify: that is not yak shaving, that is just plain old procrastination. Yak shaving includes tasks that you have to complete in order to do whatever your original intent was. For example:
That is yak shaving.The example (and definition) in the actual article disagree with you:
"You want to bake an apple pie, so you head to the kitchen. In the hallway, you notice some paint chipping on the wall. So you walk to the hardware store for some paint."
You obviously don't need to deal with the paint chipping before baking an apple pie.
Wikitionary gives both definitions: a blocking task or a procrastination detour
My feeling of things related to yak shaving:
Rabbit holes - intentionally following some thread of associations looking for some insight or unexpected solution
Yak shaving - While working on something important you iteratively find something more important that you feel you need to deal with first. Supposedly but not necessarily it's something you have to deal with to be able to solve the original problem.
I agree that the articles example of yak shaving is a special case of yak shaving where it isn't very clear that the shaver feels that the distraction is more important. But I suppose such feeling is always a bit implied in the word distraction.
Create a GitHub repository and create a journal repository and create a markdown heading for each entry. It works.
I'm on 4 pages of 100+ journal entries each. See my profile, I journal computer ideas, algorithms in the open.
Using WordPress or using complicated software shall take time away from writing regularly. And you need to open a document and write, not abandon your blog due to forgetting how to post
This is very much an easy trap to fall into! What helped me was not sweating over the small stuff and setting up an instance of Grav, though I think that most of the turnkey blogging solutions out there would work (e.g. Ghost/Bolt as well, maybe not self-hosted Wordpress as a first option due to large surface area): https://getgrav.org/
What I really like about that solution in particular is that it is flat-file based and also has an admin web dashboard that's a separate plugin that can be enabled/disabled (some might prefer writing text files directly, with front matter and all) and has separate URL path that can be put behind basicauth (in addition to built in auth), client certificate auth or anything else.
It's not perfect, of course, and has given me the occasional headaches, but it's also good enough for my blog: https://blog.kronis.dev/
That said, I still struggle with my homepage - instead of going back through 5+ years of projects and describing all of the noteworthy ones, putting up a few galleries of screenshots, listing technologies, ordering them by relevance and also making sure that it doesn't contain too much data... it's just sitting there, on my TODO list. It's been that way for a while now.
I want it done. But I don't want to do it.
When quasi-blogspam articles like this rise to the top so quickly, one has to wonder whether it’s the result of vote manipulation.
But even the best of us are prone to fall for it, and sometimes they even produce excellent results, cf. Donald Knuth and the TeX / Metafont ecosystem:
Between 1977 and 1979 computer scientist Donald E. Knuth of Stanford University created the TeX page-formatting language and the Metafont character shape specification language, originally as a way of improving the typography of his own publications. [...] -- https://historyofinformation.com/detail.php?id=3339
Does this really happen?
My experience is that programmers always try to make things as simple as possible, and when they fail at that, it's because they don't know how, or don't have enough time, or maybe the "simple" solution isn't persuasive enough that it covers all the cases, so a "more complex" version is preferred, or something like that; not because they forgot "whoops" I was supposed to make things simple not complicated.
The only times I have heard "KISS" suggested in earnest have been from bad managers.
> But even the best of us are prone to fall for it, and sometimes they even produce excellent results, cf. Donald Knuth and the TeX / Metafont ecosystem:
I don't see how this has anything to do with failing to keeping things simple, yak shaving for sure, but this yak (if it's a yak) did need the shave: there weren't any typesetting systems comparable to TeX at the time (and by some opinions there still aren't). What else can you do? Have someone spend hours typesetting and resetting a thousand page book every time there's an error, or turn the job over to a computer and automatically typeset it?
This is just solving problems. Solving problems you have is good, and where people go wrong, it's when they are solving problems they don't have (but perhaps think they might), or perhaps they underestimate how much of their problem the computer could actually solve.
I am at least 18 months into exactly the same hole. And it isn't the first time.
I've been using Obsidian[1] and a few plugins like Incremental Writing[2][3] to help me write. Focused less on publishing and more on writing for me.
[0]: https://www.goodreads.com/book/show/34507927-how-to-take-sma...
[1]: https://obsidian.md/
[2]: https://supermemo.guru/wiki/Incremental_writing
[3]: https://github.com/bjsi/incremental-writing
Uniqueness, mystery, narratives and humor/silliness are probably big drivers of attention on forums and news sites. Like the other commenter suggested, the gold is typically in the comments. I don’t have data to back up this assertion, but it would make for a good study/article.
The magic is in the Ren & Stimpy reference.
So now instead of fixing my bug I’m rewriting API call sites across my project.
I quite like the Malcolm in the Middle[0] example of yak-shaving, though it's a combination of both blockers and distraction.
[0]: https://www.youtube.com/watch?v=8fnfeuoh4s8
> yak shaving - Any seemingly pointless activity which is actually necessary to solve a problem which solves a problem which, several levels of recursion later, solves the real problem you're working on.
I guess that opens the debate to does the code actually need to be refactored? Sometimes not, but I have a very hard time leaving a 2000 line function alone, or a class with many levels of unnecessary inheritance.
What I’ve started to think is that there are people who get things done, and people who refactor.
People who get things done ship code fast. The good ones know when to make trade offs of purity vs practicality. The bad ones write unmaintainable code. They tend to view programming as a job, and code quality as a burden. They may refactor and make unrelated improvements, but it’s uncommon.
People who refactor still get things done, but most of their work have rabbit holes tacked on. They delivered a bug fix, but they also greatly improved the test suite and tooling. They tend to value purity, best practices, and might view programming as a craft/art. The good refactorers make the high value changes that are a net benefit to the team; they might care about cleaning up important parts of the code, improving developer experience, or adding test coverage to critical functions. The bad refactorers rewrite a bunch of code because it wasn’t pure, and the team, customers, and business have no observable effect from it.
I think teams need both kinds of people on it. Too many doers will lead to fast progress at first, but eventually grind to a haunt. I felt this was a HUGE problem at my team in AWS, and a major factor of why I left.
Too many refactorers is equally problematic. Your code will be of great quality, but velocity will be unacceptable for the business.
I personally am a refactorer. probably more of a bad refactorer than good, but it’s something I’m working on.
Maybe this is a rationalization for my behavior so that I believe it’s important, but my time at AWS shipping 3 features a year with a team of 16 says that code quality really does matter.
It's a matter of focus and intentionality.
I clicked on this article because it applies to me (I constantly yak shave), but I’m a bit disappointed with how terse it was.
Meanwhile, I can't get refactor-only commits through because nobody wants the code to be touched unless absolutely necessary.
We're in the middle of migrating a massive PHP codebase to Java. The code I'm talking about is newer Java code. In a few years, people will be wondering why the Java code is as much as a mess as the PHP code and, if I happen to still be around, my response will effectively be "I told you so" (in kinder, more productive terms).
I've basically determined that my only option to ensure continued or improving code quality is to combine refactoring and bug fixes in the same merge request, while still keeping them in separate commits. That way whenever I touch a part of code for bug fixing or whatever else, I leave it behind in much better state than it was before.
I agree, in practice I think this is the best option, with some kind of timebox for the improvements made.
One thing I'd like to add is setting up some kinds of tests. If nothing else is available, E2E tests for the critical paths of the business are a good start. For (micro)services, getting API contract tests to work is also invaluable.
The guy the goes around blasting bugs like there's no tomorrow looks good to the boss. When he leaves someone will have to refactor his mess and that's wasting time again.
I have had this conversation yesterday, and the refactorer asked this very question. Here's my answer:
The question is improperly formulated. With your behavioral patterns of immediate refactoring, the question seems to be: "if I don't refactor this code NOW, who will?".
I'd say that if you don't refactor the code now, someone else, maybe future you, may refactor it later.
Most sane companies will protect engineering from impulsive feature requests and will add them to the backlog for future consideration.
I'm trying to instill the same protective mindset in my teams, and help them not do refactorings immediately but rather consider them as potential work as dedicated items in the sprints or so.
Doing so, prioritizing becomes a natural part of the refactoring/tech debt/tech risks agenda, because we have an overview of the work to do globally.
I guess this is delving into queue theory and how the work queue is growing to infinity because there aren’t enough workers.
I miss personal projects
I’m still trying to internalize this hah
It’s about “necessary” things to achieve a goal, without appropriately weighing costs vs benefits nor considering alternative solutions (perhaps making a chocolate pie instead).
In this scenario you are the one focused, the non-technical people that shuffle tasks around playing 'agile' are the handicap. It could take a couple of hours or a couple of days to get that logging done but explaining to the non technical manager (who refuses to learn) why this needs to be done is a task in itself that cannot be underestimated.
I’m sorry, but this is backwards. Bugs are many times caused by badly written code and you can tell when it’s the case. Refactoring the code many times fixes the issue without ever having to figure out where the needle was in the haystack.
I guess in every field there are platitudes and prescriptions. At the end of the day, I try to follow first principles and ignore them and just focus on building a great product.
What I see in this article is a disregard for the costs associated with context switching. My argument is, if you think you can handle the rabbit hole, and you think those related tasks will need to be done anyway at some point, head off to Wonderland. Because you have the context of the situation fresh in your temporary memory, so you’ll get it done faster than if you switch contexts and come back later.
Overall I disagree with this article, both in it's definition of yak shaving (as being unrelated to what you're doing), and in it's assertion to never refactor and fix a bug in the same PR (now I'm not saying you should refactor things every time you fix a bug of course).
With this kind of framing we can look at the cause of yak shaving as a failing of an individual, rather than a lack of an accurate and holistic view of what the task entails given the current state of the system.
My point however is not to discuss this. What bothers me, and only a little, is the label chosen to describe situations such as these. Why 'yak shaving' and not something else?
I mean, the Ren & Stimpy connection is meaningful for the author, and that's ok. But if every time I want to refer to it I have to explain why it's named as such, or even explain who Ren & Stimpy are, maybe I'll be better served by some other, perhaps more appropriate label.
Calling it 'Going down the rabbit hole' is no doubt better, at least to me, but not completely. This expression captures a different mood, namely that of finding ever more connections in an endless stream that does not necessarily make me forget my original goal. For instance, while writing a paper, many times I find myself going down the rabbit hole, ending up with these monstrous footnotes that try to record how deep that rabbit hole goes. But when that is done, I go back to the main topic and move on.
So what could I call it other than 'yak shaving' or 'going down the rabbit hole'? I'm open to suggestions.
It may be more recognisable, but I wouldn’t say it’s better. The metaphor of going down the rabbit hole has you go deeper into the same subject while yak shaving has you go into increasingly tangential tasks to the point an external observer wouldn’t recognise your primary goal.
In other words: the longer you spend going into the rabbit hole, the more you familiarise yourself with the matter; but the longer you spend yak shaving, the farther away you are from finishing the original task. Yak shaving is antithetical to going down the rabbit hole.
Nothing else about the hell that one in is in when they are yak shaving is the least bit funny. At least give us this little bit of joy.
This person has obviously never been in a situation where to get the data to fix the bug you need to modify the instrumentation, which requires a new data format because you are the first to use dicts of dicts of floats, and when adding that you end up with a random seg fault, so you debug that and find out that the stack frame pointers disappeared last week when GCC was upgraded by a vendor patch on your colleague's laptop, but not yours, and so he checked in a "temporary" fix for that. Frame pointers restored, you find an off by one in the serialization of floats which you fix. So you go to collect your data but the data aggregation system, which said it supports your data type in fact does not in the current version, so you upgrade it, but for that you need a different GCC update. But that GCC needs a different libstdc++ which causes compile errors in your app. So you find yourself in the Makefile adding a way to use a local copy of libstdc++, and you can't remember why you were even fixing the bug, because in the meantime the docker image used for the mock database has been updated, adding a new bug that masks the bug you were supposed to be solving (but you won't find out about that for 3 more months).
Your scrum update for 6 days running is "maybe tomorrow", and your cat runs away because you are so preoccupied with the bug you forgot to feed it, and your yak needs shaving because in a daze on the way home from another day wasting your life at this stupid job, you forgot to pick up razors.