If you want to grow as a musician, be the worst person in the band.
That’s conventional wisdom passed down from teacher to student, especially when the student starts to get a little too arrogant about their skills. If you’re always the best musician around (or you always believe yourself to be), you won’t let other people get their time to shine. You will always try to get your way. You won’t be open to learning from other people.
I think software development is the same way. That goes even more so when you’re working on a community-developed project, where there’s no one person paying everyone’s salary and everyone is doing it because they get something out of it.
Don’t Throw Data Away
The other day, longtime contributor ReverseControl filed a bug, issue 2523. “When I open up the network traffic debug window and change the time scale of the graph, all the data gets throw away and replotted.”
This bug report is pretty good! It has a clear description of the problem, and it’s something I’ve noticed and that’s bugged me too (no pun intended). I didn’t think to file it, so it’s great to see that someone else did.
You may have noticed that I like bug reports. I get energized to look into them and make someone’s life easier, because often these bugs are unintended behavior that just needs someone to look into them and do the right thing instead.
I created a pull request, PR 2934.
Code and Discussion is Better Than Discussion
My code wasn’t obviously correct, but it wasn’t obviously incorrect either. The right code we’ll eventually merge will look, in part, like what I wrote.
I realized something when I tested my changes locally. I wasn’t sure what the code shoud do. I knew what it shouldn’t do, but that’s only a start.
This could have gone a couple of ways. I could have slowly backed away and shown no one the code. This is easy; only I would know that I tried to do something but didn’t complete it. I could justify the couple of hours I spent on it by posting a couple of wise comments on the ticket, discussing how one might do the work and some pitfalls to avoid along the way.
That wouldn’t have been a bad thing. That might have been a very good thing, if it inspired a new contributor to pick up the bug and write some code.
I could have submitted my PR and argued strongly for it, in that it addressed the bug as reported. We’re no longer throwing data away.
That wasn’t the right thing to do though, because it wasn’t clear what the right thing to do is.
A Story is a Promise
In the world of agile software development, not big-A Agile like a consultant might try to sell you, but little-a agile, like “favor people over process, favor working code over voluminous design documentation, and test your assumptions”, one of the central units of software design is the conversation.
Both big-A and little-a agile call these “stories”.
ReverseControl started a conversation by saying “Here’s some behavior that doesn’t seem right”. I picked up the conversation by agreeing and saying “Here’s some code that addresses the story as written”.
I went further by saying “… but I’m not sure the results are what we want.”
In the little-a agile world, a story isn’t an end in and of itself. It’s a bookmark. It’s a placeholder. It’s a promise that the person actively solving the problem can talk to the person who identified the problem so that they can both understand the problem as it really is.
The Worst Musician in the Band, Paraphrased
If we were all sitting in the same room, like the original Extreme Programmers did (Whole Team, I imagine the conversation might have gone something like this. As it is, it did go something like this, paraphrased heavily.
Patrick picked up on my hint. “This seems weird,” he observed with sagacity and politeness.
Michi came along, saying “This seems weird to me too. Now that we’re not throwing away data, we have a viewport problem.”
Viewport. That was the word I was looking for. When I knew what I was seeing wasn’t right but I couldn’t explain it, I was looking for the word “viewport”.
“Aha,” said ReverseControl. “That sounds right.”
“Let me come back with some code,” Michi said.
Patrick could have coded this. ReverseControl could have coded this. I could have coded this. Several other contributors could have coded this. Many people reading this could have coded this.
After Michi said “viewport” and “circular queue” and did some envelope math on sample rate, the solution was a lot more obvious.
Maybe someone smarter or paying more attention or possessing more free time than I did last week would have picked up on the problem before I did, and that would have been fine. Eventually someone would have realized exactly what we needed here, or would have retraced my steps and pushed just enough to have the conversation that we had to reach to the point we reached, so that the solution was obvious enough that a decent programmer could implement the right solution in a day or two of work.
I should also give credit to both Patrick and Michi for embedding video examples of what they saw and how it works. That saves everyone else from having to check out the PR, compile it themselves, then figure out how to manipulate the GUI to test what they want to test.
As a side note, there’s an additional conversation about an expanded scope of what the eventual solution could be, but we communally decided that expanding the scope of the problem isn’t necessary because we already have an effective solution for that problem. That’s the sign of a mature engineering culture: not doing things that aren’t necessary.
“Everyone Is Awesome” is My Jam
I’m not amazing because I threw a little bit of code at the wall and a bunch of people said “Nice try, but that’s not quite right.”
My goal is not to be awesome, and I’m not awesome because pushing a PR gets people to look at code. (Pushing a PR that’s obviously not quite right is different from pushing a PR that’s obviously wrong. One is more valuable than the other.)
Everyone involved is awesome because a bunch of us looked at something that was obviously not right, looked at something that was a little less wrong but still not right, and then figured out what was right.
When this code gets merged, next release (probably 1.14.6) will be a little more awesome because we all worked together and made things a little bit better.
That, to me, is satisfying.
I like when I write good code and it gets merged and people use it and appreciate the feature that makes their lives a little more pleasant.
I really like when I help other people do the same.
Writing the right code is important, and Michi deserves a lot of credit as always, but figuring out how to tell if it’s right took a lot of input. This could be you: even if you’re not a devoted C++ programmer or someone who hears the words “viewport” and “sample rate” and thinks “Oh, I’ve done something like that before and know how the solution should look”, being able to play with something and figure out how it should look when it’s done is incredibly valuable.
Some days I’m a better musician than others and other days I’m a lot worse than everyone else, and that’s fine. It’s more important that we’re all playing the same tune and enjoying ourselves and learning from it.