Yesterday Josh Thompson, one of my Rubber Duck Session clients, proposed a novel idea for deliberately practicing coding skills: take a popular open-source project with a good test suite, delete a class, and re-implement the class using only the tests as a guide. Then, compare and contrast our implementation with the original!
I suggested the Rake codebase, and this video is an unedited recording of the session. Enjoy!
I am mildly out-of-sorts as I write this. The front of my favorite local dive appears to have fallen off, complicating my afternoon plans of meeting my mom there. Entropy is everywhere!
What dismays me about technology is this: not the machine itself but the way its architecture echoes outward, imposing a grid of quantification on everything it touches.
This article about life in Silicon Valley is powerful and a bit painful. I keep saying, you can’t do this shit 8-12 hours a day and not have it warp your outlook.
A programmer spends thirty years in the industry, and one day they designs a beautifully simple and elegant programming language. Or API. Then they go on the conference circuit pointing out the virtues of simplicity, and bemoaning why other developers can’t just keep things simple.
What’s omitted: It took them thirty years to figure out what was “the simplest thing that could possibly work”.
The simplest step isn’t always the easiest step, because simplicity comes from wisdom. Sometimes the most accessible first step is to do the thing you know is overcomplicated, but you don’t yet have the perspective needed to simplify it. Once it’s in use, you’ll start to see where to pare it down.
Example: I kicked off a Patreon recently. I made the tiers too elaborate. I knew I was making them too elaborate. But I couldn’t figure out what to drop and what to keep.
Now that it’s been up for a few weeks, I’m getting a much better idea of what makes sense for the tiers, and I’ll be simplifying it soon.
Example: I usually don’t figure out what the “core idea” of one my talks is until I’ve given it at least three times. Then one day it finally dawns on me what I’m really getting at, and I reorganize the talk to emphasize that core idea.
“Do the simplest thing that could possibly work”. “Minimum viable product”. These concepts are supposed to be enablers of action, but sometimes they are obstacles. We often start out jumbled full of thoughts and only later do we realize which one was central and which ones were peripheral.
Sometimes the most expedient step to take is to start with elaborated complexity, and give yourself license to pare down instead of add.
Last night I went to my first fashion show ever and it was amazing. It was a celebration of embodiment and of the endless conversation-with-past-and-future that is art. I highly recommend attending one if you ever have the opportunity.
More broadly, I strongly endorse adopting the strategy of defaulting to “yes, please” when someone recommends or invites you to something you’ve never done before. I don’t think I realized just how much I’d internalized the philosophy of “oh that’s not the kind of thing I do” until I started deliberately saying “yes” to new experiences.
The problem with “that’s not my kind of thing” is that eventually, you stop seeing other possibilities at all. They become part of the background noise. They become the restaurant you’ve passed so many times that you never think of trying it out.
Let's see how I did:
- ✔ Book May travel. Done! Off to St. Louis again in a week and a half, look forward to more livestreams of Jess and I yelling at computers! 😂
- ✔ Update my website. Done! I'm really happy with this accomplishment, for the first time my site actually reflects everything I do.
- ✔ Invite a half-dozen new RubyTapas guest chefs. More than done! Lots of great new guests coming up…
- ❌ Go through my stupid mail. Well, I went through all my email. The snowdrift of snail-mail continues to accumulate.
- ✔ Push consulting paperwork forward. Done.
- Catch up on RubyTapas tasks. Done. Intros and promos and edits and tagging, oh my!
- Get two me-authored RubyTapas episodes ready for the team. We need to fill some gaps in the schedule, and I have some episodes on async processing just waiting to be written and recorded…
- Get another episode of The Cache Flush out.
- Keep working out on a daily basis.
- Edit that video about building chatbots in Ruby.
- Ugh can we just leave it at that for now? I want a win.
Until next time… thanks for reading, and feel free to reply!
First off, if you got another duplicate SIGAVDI recently I apologize. I have now indefinitely disabled the automatic RSS-to-email rule in Drip, because they can’t seem to reliably record the fact that a given entry has already been sent out.
I’m writing this from in Nashville, which is a wonderfully funky little cafe and I recommend it. Have them pick a sandwich for you.
I’m in Nasvhille because I spent the last few days at , which is apparently the “more tech-focused Agile conference”. This still makes me wonder what they talk about at all the OTHER Agile conferences, but I’m sure I’ll find out one of these years.
I opted to speak at deliver:Agile even though it conflicted with RailsConf in part because I’m making a deliberate effort to swim in bigger ponds. One of the things I really appreciated about this conference is that I didn’t meet anyone who seemed like they’d be likely to call themselves “a Java programmer” or “a Ruby programmer”, etc.. Most of the attendees were developers, but as a crowd everyone seemed to be more focused on value and results than on specific technologies. It was refreshing.
People to pay more attention to, post-deliver:Agile, an incomplete list:
I also got to meet Rebecca Wirfs-Brock in person 🤩🤩🤩
Random thought while running today: there are some things you just can’t do solo.
I remember being a young programmer and reading about Agile practices and getting all excited and wanting to “be agile” even though my team wasn’t. And the fact is, I could and did do some of the techniques associated with Agile, like TDD. And they were quite helpful. But I wasn’t “being Agile”, I was just using TDD.
I have no doubt that individuals like me practicing Agile-associated techniques were one of the factors that eventually caused many organizations to “go agile”. At the same time, I’ll bet the same phenomenon also fed the fallacy that Agile just meant adding those techniques to your repertoire.
The same goes for making a sociotechnical system resilient: by definition you can’t do it solo.
There is a qualitative difference between the numbers one and two. Everything after that is quantitative, but two is important.
For where two or three are gathered in my name, there I am with them.
— Matthew 18:20
I’ve been reflecting on just how much of my life has been ruled by anxiety. I don’t think I ever really understood how large a role it played because it was the air I breathed. It took experiencing periods of a week or more without anxiety for me to really start to see it.
I’ve often said I like the person I am when I drink, better than the one I am sober, and there’s a simple reason for that: alcohol turns off my anxiety. I make choices based on what I actually want rather than based on what I’m anxious about.
Fear is unavoidable, but short-lived. Either the scary thing happens or it doesn’t. Either I do the thing I’m afraid of or I retreat to safety.
Anxiety is long-acting poison. A holdover from when the longer we roamed the tall grass the higher the probability we’d be attacked by a tiger.
Tasting anxiety-free life for even a week is like tasting sushi for the first time. My standards are permanently raised. I don’t have to live with this fist in my guts? Sign me up.
OK, let’s see how I did.
✔ Prep to speak at in a week. Done. I put a solid couple days of work into updating the No Return talk, and I’m pretty happy with the edits.
✔ Finish landing page/video for YES! I finally finished it!!! 😁
❌ Edit video on building chatbots in Ruby. Nope, but I shouldn’t have carried this forward in the first place. That was way too much to expect in a week.
❌Nail down my first part-time contracting gig. Jess pointed out that “nail down” is not a thing I can actually do on my own. The best I can hope for is “push forward”, which is exactly what I did.
❌ Start coding in earnest on That One Side Project I keep flaking on. Again, this was overcommitting so I don’t feel bad about not touching it.
✔ Post another episode of The Cache Flush.
✔ Start working out again on a regular basis!
✔ Meet lots of cool people at deliver:Agile
✔ Investigated a to build .
This week’s meetup:
(This is something new… lately I’ve been making an effort to choose a new meetup to attend every week that I’m in town. I think I’m going to start explicitly listing the meetup I pick in SIGAVDI so I actually remember.)
For the rest of this week and next week…
Book May travel.
Update my website. This past week it really started to bug me that I don’t actually have a homepage that lists all the stuff I do: speaking, consulting, screencasting, writing, podcasting, etc.
Invite a half-dozen new RubyTapas guest chefs (I’m always looking for more, hint hint… if you have something to say to this audience, jab that “reply” button!)
Go through my stupid mail. There is enough stacked up that it is a Task.
Push consulting paperwork forward. I forgot how much lead time there was in this game…
I think I’m going to leave the last couple of slots open because I feel like something important is going to occur to me later.
And that’s it for today. As always, thanks for reading and please reply!!!
I’m writing this from Harrisburg, Pennsylvania. I spent the weekend with my kids down the road in York, and today I’m headed back to Knoxville.
One of my daughters asked me why I go to so many conferences, including one over her birthday. The temptation when a kid asks a question like this is to say “I have to”. But the truth is, I don’t have to. There’s very little we have to do. Some choices just have greater consequences than others. (And the consequences vary unevenly based on our circumstances/privileges.)
So I told her the truth: I choose to go to conferences. I choose partly because it helps with my work, and partly because I get to see old friends and meet new ones. But most of all, I go because I get to help people and sometimes change lives. I don’t just imagine this to be the case; I have countless emails and postcards and personal conversations to confirm it. I have a ministry, and my software conference presence is part of it.
I also choose my children. I choose to use my frequent flier miles and credit card points and income to fly up to see them for weekends, because summer break is just too long to wait, and because I can.
My children are not having the childhood I planned and tried to build for them. With changing circumstances, I have reconsidered many of the values I once took for granted.
I used to tell myself (and everyone else) a story about doing everything out of responsibility and obligation. Everything I did was because it needed to be done. There was no personal calling. There was little choice. It was an easy story to tell: there I was, virtuously bearing up under great responsibility, plodding forwards in the only way open to me.
I don’t know what my kids are going to think of me as they grow into adults. One thing I hope they see me model now, though, is agency. I want them to learn from me that people don’t act from opaque “have tos”. No matter what story we may tell ourselves about constraints and obligations. We choose, either consciously or unconsciously. And then we must acknowledge our choices and their consequences, and move forward.
At a conference recently someone asked me: as a Rubyist, what do I think of the Go language? I said: “ uh… it exists.”
There are people who spend their days on Reddit and Hacker News delivering hot takes on every technology, idea, or opinion that comes down the pipe. Sometimes I feel the need to remind junior devs that if that’s where they are getting their perspective, they are getting their point of view from a self-selecting subset of technologists who have nothing better to do than Have Opinions On The Internet all day.
My hot take on hot takes? As a software developer it’s important to know that technologies exist, and at least a vague sense of where they fit into the ecosystem. Beyond that, you do not need to have opinions. You do not have to have a “take” in order to be a serious player.
Stories, though. Stories are another, uh, story. By all means collect stories! And tell them at every opportunity.
Just don’t mistake stories for universal truths. Every story has a context.
OK, let’s see how I did.
✔ Visit the kids over Easter/Passsover.
❌ Finish landing page/video for But! I made some solid progress. All that’s left is to edit the video I made for it.
❌ Edit video on building chatbots in Ruby. No movement.
❌ Nail down my first part-time contracting gig. I’m a lot closer but I haven’t signed contracts quite yet. Contracts are tedious, yo.
❌Start coding in earnest on That One Side Project I keep flaking on. Sigh.
❌ Post another episode of The Cache Flush. Maybe I’ll get this done before it’s time to get on the plane.
Bonus points (stuff I did that wasn’t on the list):
✔ Attend a users group meeting. I went to for the first time and had a great time afterwards over beers. I even recorded some more interviews for !
✔ Clear out my !@%*ing work inbox. There were some things in there that were really stressing me out too.
✔ Help my friend Amy with , which you should definitely go see if you are attending RailsConf. (This sort of thing is one of the reasons I started – I’d love to spend more of my time just helping boost new voices in software.)
✔ Mooch some boilerplate contract templates from a friend and customize them for my upcoming consulting clients. This was more work than I expected.
✔ Get started mentoring a friend in how I run RubyTapas.
✔ All the usual RubyTapas editing, copywriting, script review meetings, etc. saw some new behind-the-scenes videos this week!
Yep, another week of carrying the list forward from last week. Ah well, they can’t all be hyperproductive. This week:
Prep to speak at in a week.
Finish landing page/video for
Edit video on building chatbots in Ruby.
Nail down my first part-time contracting gig.
Start coding in earnest on That One Side Project I keep flaking on.
Post another episode of The Cache Flush.
Wish me luck!
I can’t brain today and I’m not sure why. I haven’t drunk much alcohol in the last few days, I have received more than adequate cuddles, and I slept way in this morning. Maybe it’s the weather? I’m writing this on the porch in the windy sun between two storm systems.
This week I've been thinking about the tension between catching errors at compile time and catching them at runtime. On the surface level this one seems like a no-brainer: the early you catch a problem, the better.
But in my [mumblemumble] years of static-language experience, what I observed was that the more you focus on pushing all errors into the the realm of static compile-time verification, the more catastrophic and difficult-to-debug the runtime errors become. And there are always runtime errors. Even after you've eliminated null from your programming language.
The resilience engineering community has a counter-intuitive approach: instead of trying to eliminate errors early, actively cause them in production. Then learn how to tweak your sociotechnical systems so that they gracefully handle failure and mitigate damage.
Someone will always object: this is not an either/or. Let's eliminate as many errors as possible at compile time, and make the runtime errors easier to handle as well!
In practice, these seem not to be two dials you can turn up simultaneously. Gracefulness at runtime and static verifiability are design forces in partial tension with each other.
Is this such a surprise? It's just the oak and the reed again. The more rigidly we structure things the more jagged they are when they crack.
I know where I fall, now. I am an oak learning to be a reed. My life is falling forwards. My eyes hurt and my new glasses aren't here yet and my neck hurts because my spine is fucked up and my hand hurts because my ulnar nerve is impinged and parts of my business are failing or falling behind and my kids are far away from me and I probably don't have enough money to get through next month and two more boards in my deck have cracked and the mail is stacking up and once… once upon a time I believed I was going to get my whole house in order before I moved forwards.
No more. My house will never be in order and everything will always be falling apart and this is fine. Because there's beauty in the breakdown but more importantly, there's new order and new life and new happy coincidences. There's new love and new vistas and new collaborations and new restaurants to try with new friends and nothing is ever the right solution forever. Thank goodness.
The big news this week is that I finally started a Patreon. It's still a work in progress. My favorite bright idea was to make a lot of the tier benefits be about sponsoring other people rather than about getting rewards for yourself. I hope this resonates with patrons.
In the process of kicking off the Patreon, I repurposed the name of a now-defunct microblog I used to write and created a new Slack workspace called “Padding Bits”. If you like SIGAVDI but wish it was more real-time (and even more interactive!), you can now join in the fun for as little as a buck a month 😀
Let's see how I did:
✔ Play Super Smash Brothers with the children who are presently interrupting the writing of this email. Done! Granted this one was kind of a gimme.
❌Create a landing page for
❌ Edit video on building chatbots in Ruby. Nope.
✔ Launch my Patreon because why the hell not. Yes!
- ❌ Migrate off of Drip for mailing list hosting because they are a total garbage fire since their acquisition. This was overly ambitious but I DID start a Convert Kit trial. They've been the front-runner all along, and when I found out they have Patreon integration they became even more attractive.
- Bonus accomplishment: learn about the Kuberdoobers with Jessica!
This week's goals:
- Attend DevopsDays/ServerlessDays/MapCamp Atlanta and learn whatever it has to teach me.
Finish landing page/video for
Edit video on building chatbots in Ruby
- Evaluate Convert Kit.
- Nail down my first part-time contracting gig. (I'm still interested in talking to potential clients!)
- Start coding in earnest on That One Side Project I keep flaking on. Because I really, really need to write code.
As always, thanks for reading!
During my RubyTapas script review with upcoming guest chef Kerri Miller, we spent some time refactoring a method toward lower complexity. In the process we needed to isolate it from its dependencies, and we used Ruby's OpenStruct library to quickly accomplish it.
It's been a couple of weeks. Since last Tuesday I've been in St. Louis. and I . It was highly educational.
And we went to the symphony.
And the art museum.
But mostly we ate really good food.
Some of it highbrow.
Some of it less so.
That is an authentic St. Louis ““, a $6.50 pile of sloppy late-night goodness.
A mistake I have made over and over again: thinking of life in terms of forks in the road. Big choices on which everything hinges.
The truth is, there are few choices in life that can’t be a “yes, and…” with some creativity. And most choices can be amended.
Just move. Direction is always adjustable.
I’m thinking of starting a Patreon (just do it, Avdi! Direction is always adjustable!). I’m trying to figure out what rewards to offer subscribers. Thoughts? It can’t be anything that adds a significant amount of work to my weeks.
I should print stickers. Everybody likes stickers, right?
I find myself badly wanting to sit down and code lately. It’s been so long since that was a central part of my day. This urge was one of the motivations for soliciting new . Ironically, one of my first gigs may be more about video production than coding (more on that soon, hopefully).
A lot of it is just that I miss the relative simplicity of making shit work instead of deciding what shit needs to be done.
I’m also thinking of doing a talk on communicating technical ideas. I spend a lot of my time these days coaching other people on how to do that.
I’m really struggling with my goals this week. There are a lot of possibilities. Let’s talk about the last two weeks first.
✔ Stream/record some kind of collab with Janelle Klein. Done. It’s probably not going to see the light of day, but it set us up for future recordings.
✔ Finalize my new working arrangement with Cohere. Done. Not in the way that I had anticipated, but I made a decision for the time being and it’s time to move forward with other plans for now.
✔ Get to a tentative agreement on a consulting gig. Done! This was a stretch goal but it happened 🙂
✔ Nail down April travel plans. Done. I’m spending more time traveling than home this month. This is fine.
❌Clean up the weight room and do some lifting. Nope. But! I ran and lifted here in St. Louis!
✔ Sundry RubyTapas and meetings and related work.
✔ Attend a new meetup Done! Well, sort of. My original plans fell through (who schedules a meetup for 6PM?!) but I made it back to the Knoxville Devops meetup.
✔ Attend some part of . YES! Janelle and I caught doing interesting drum things, and later attended the poetry slam finals which were fantastic.
What am I doing this week?
Play Super Smash Brothers with the children who are presently interrupting the writing of this email.
Create a landing page for
Edit video on building chatbots in Ruby
Launch my Patreon because why the hell not
- Migrate off of Drip for mailing list hosting because they are a total garbage fire since their acquisition.
It's been two weeks since the last SIGAVDI. I visited my kids in Pennsylvania last weekend, then came home and went into a bit of an emotional tailspin. As of today (Sunday) I'm feeling a bit better. I attribute the improvement mostly to getting some much-needed human touch and socialization over the past two days. It's amazing how much these things help.
Heads up: I'm officially looking for a part-time consulting client. There's some more info here; feel free to pass it along!
Some premises about my relationship with unit testing:
- I like test-driven development.
- I like driving out individual object design small, isolated (e.g. no database) unit tests.
- I think of these unit tests as a design aid, full stop. Any help they provide with preventing regressions is gravy.
- I treat unit tests as disposable. Once they have served their purpose as design aids, I will only keep them around so long as they aren't getting in the way.
These four premises are strongly interconnected. Take away #1 (test first), and tests are no longer a design aid and none of the other points are valid. Take away #2 (isolation) and we get into integration test territory where there's a much higher possibility of tests having regression-prevention value. Take away #3 (design focus) and the other points lose their justification. Take away #4 (disposability) and I spend all my time updating tests broken code changes.
This makes it easy for me to find myself at cross purposes with others in discussions about unit testing, because often they come into the conversation not sharing my premises. For instance, if your focus in unit testing is on preventing regressions, you might well decide isolated unit tests are more trouble than they are worth. I can't really argue with that.
A recent conversation on this topic inspired the thought from the driving-design perspective, maybe unit tests are really just a crutch for languages that don't have a sufficiently strong REPL experience. While I don't think this is strictly true, I think the perspective shines a useful light on what we're really trying to accomplish with unit tests. I almost think that what I really want out of unit tests is the ability to fiddle with live objects in a REPL until they do what I want, and then save that REPL session directly to a test for convenience in flagging API changes.
That conversation also spawned the idea of immutable unit tests: unit tests that can only be deleted, never updated. A bit like TCR. I wonder if this would place some helpful incentives on the test-writing process.
So I tweeted about some of these thoughts and someone was like “don't say that in public, you might lead junior developers astray”. And it got me thinking about how I've said similar things in the past. There's a trope in the developer practices conversation that goes: “there are some things experts do which we shouldn't talk about in public, because someone impressionable might get the wrong idea.”
The more I think about this, the more I wonder if it's healthy or constructive. What do you think?
Sometimes you make me feel like I'm living at the end of the world.
— The Cure, Plainsong
I've been thinking and talking to friends about apocalyptic relationships. That's my phrase for relationships that are premised on a model of “you and me against the world”. Imagine the post-apocalyptic film or novel of your choice, with the two romantic leads braving a treacherous wasteland full of bandits and mutants, and you have the right idea.
Apocalyptic relationships are inward-facing. They survive on the energy of “anti”. They have only one speed: intense. They draw their intensity from scarcity. You and me: we're the only ones who can help each other through this hellscape.
For many years I was in a relationship that only really worked when it was in the apocalyptic mode. Now I feel like I'm keenly sensitized to the “smell” of potential apocalypse. I've been talking to friends about their experiences with apocalyptic pairings. Once likened it to a “Bonnie and Clyde” feel. A relational suicide pact. They all agree though: these relationships are engrossing, intoxicating, profoundly difficult to move on from, and they feel like nothing else could ever come close in terms of intensity of feeling.
I'd be curious to hear your experiences and thoughts, if any.
OK, let's see how I did:
- ✔ Create and launch a marketing campaign for Flawless Ruby. So the campaign turned out to be “just get it out the door and announced and worry about further marketing later” and by that definition I succeeded!
- ✔ Publish “Beyond Business Cards”, a recorded discussion I had with Jessica Kerr about how to meet people at tech events.Yep, along with an experimental microproduct consisting of a cleaned-up version of the recording plus a little PDF we put together!
- ✔ Get next week's RubyTapas episode out the door.
- ✔ Visit my kids.
This week my friend Janelle is visiting (you should check out her book!). We're mostly going to be working on our own respective projects, but I'm hoping to make some kind of collaboration emerge as well. Goals for the week:
- Stream/record some kind of collab with Janelle (IdeaFlow demo??).
- Finalize my new working arrangement with Cohere.
- Get to a tentative agreement on a consulting gig (probably over-optimistic but I can hope).
- Nail down April travel plans.
- Clean up the weight room and do some lifting.
- Sundry RubyTapas and Rubber Duck meetings and related work.
- Attend a new meetup (I have one picked out already!)
- Attend some part of Big Ears Festival.
OK, that's it for this week. Thanks for reading!