Tag: Have Backbone

Two Things True

Two Things True

On the same day I wrote about radical responsiveness, I came upon this post that seems to contradict it. I really respect Ethan Evans and enjoy his writing (especially this bit about why you fail to get promoted). And I understand the point he’s making about fragmented attention. The temptation to conflate interruptions with importance is real, and amplified by modern communication technologies. But I’m not prepared to say he’s right and I’m wrong.

For one, I believe it’s possible to be both radically responsive while remaining reasonably non-fragmented. Some degree of interruption is inevitable, but using techniques such as pomodoro can help protect focus while still ensuring important messages don’t get missed for long. Good old-fashioned discipline is required to stick to a plan, but it can be done.

The discipline gets easier with a well-configured set of tools, which is where many folks fail. Learn your tools! And not just the basic features, but the myriad of options for managing notifications, filtering messages, scheduling reminders, etc. It’s not a badge of honor to be “bad at email” or “not understand Slack” if you’re a professional in 2024.

(If any of my coworkers are reading this, they may quickly point out that as recently as last month I didn’t know how to join cell phone calls into a conference. Which… is true. But I learned! And now I know for next time).

Finally, Evans makes an assumption about communication that I don’t believe holds true. It comes through most obviously in this statement:

“Allow chaos to build up within the trivial (the inbox) to accomplish the meaningful.”

Did you see it? The assumption that messages in an inbox are trivial? Tell that to your customer who is informing you of a serious issue with your latest release, or your team member whose employment status is in jeopardy if you don’t respond to their immigration lawyer. Yes, we all get spam, but sometimes interruptions truly are critical and need attention. To lump all of that into the category of “trivial” for the sake of personal flow is a leadership fail. Communication is part of the job; sometimes it’s all of the job.

Of course, I could be wrong. Read the posts and decide for yourself.

Forth Eorlingas

Forth Eorlingas

I once had a customer call me an “idea hamster” because of how easily I went down rabbit trails of ideation when discussing the project we were working on. We had a good laugh about that turn of phrase, and I do see the value in idea generation to some degree, but ideas are easy. I’m not impressed by someone who can come up with many of them (least of all myself). What impresses me is people and organizations that can execute on their ideas.

There might be “second half of life” factors at play as well in my desire to get better at finishing. In the last week I’ve added 10 draft ideas to my blog backlog, and this will be only the first one I’ve published. At the rate I’m going I’ll never get done, which perhaps is a good thing, but still, I want to get a few of these ideas out in the wild, and that means I need to power through the writing part.

Wants What It Wants

Wants What It Wants

(I seem to open a lot of blog posts with variations on “I’ve written before about X.” Here’s another one).

Back in 2017 I wrote three posts in a row about the tension between giving users what they want and guiding them to what is best. They came to mind this week when I ran up against on of terraform‘s more annoying (lack of) features: the inability to apply changes on a per file basis. I absolutely understand why it’s not supported, but sometimes it’s a quick and dirty way to keep moving forward, and dang it, I needed it!

After a day of annoyingly overspecifying --target flags in my commands, I rolled up my sleeves and built a wrapping script that would do the work for me, essentially adding a --file flag to the CLI. I share it here as a service to the Infrastructure-as-Code community. Usage is easy:

terraform-files apply --file my-infra.tf

It’s hacky as heck, so use at your own risk, your mileage may vary, etc etc. And if you want to make it better, revisions welcomed!

A Matter of Perspective

A Matter of Perspective

In the past several months I’ve been making efforts to do more networking with technologists. One avenue to do that has been joining a couple Slack workspaces (Rands Leadership and All Tech Is Human, specifically). A few days back a conversation topic was the difference between unit tests and integration tests; a topic on which I definitely have opinions.

As part of the discussion I came up with the following distinction, which I liked enough to codify here for posterity:

  • Unit Test: Tests one “thing” (function, module, service, system) in isolation
  • Integration Test: Tests multiple “things” (functions, modules, services, systems) in combination

Inherent to this definition is some ambiguity, because a single “thing” at one level is multiple “things” at another level. What matters definitionally is the spirit of a test: is it trying to test one thing or multiple things. If the former, it’s a unit test. Otherwise it’s an integration test.

For what it’s worth, I’m a much bigger fan of the test diamond than the test pyramid. The ratio of “amount of stuff tested” to “effort required to write tests” is so much higher when writing integration tests. And they (typically) test at the “actual business functionality” level, vs at the “does this code do the thing” level. And value is all that matters.

On a tangential note, I developed another type of test diamond a couple years back. It was initially designed when evaluating taco shops along Poway Road in San Diego, but it’s applicable to just about anything you want to rate. I leave the interpretation of the diagram as an exercise for the reader (the ambiguity is a feature, not a bug).

Jud Flow

Jud Flow

Keeping a nice and tidy code repository makes me happy. Here’s the typical process I use to avoid messes:

  1. Create my-sweet-new-feature branch from main
  2. Make some awesome code edits, then commit them
  3. Make some slightly less awesome edits, commit them also
  4. Run some tests, nothing works; debug and commit the fix
  5. Decide my originally awesome code isn’t so awesome; rewrite the whole feature and commit
  6. Tests pass locally, yay! Push my-sweet-new-feature to Github and create a pull request
  7. Hrm, tests fail in pipeline; whoops, forgot a file; commit and repush
  8. Okay, tests pass now, so message team for review
  9. That’s a reasonable request, change made and committed
  10. Fine, we’ll use your naming convention; change made and committed
  11. Ugh, made a spelling error; committed
  12. Fixed moar typos
  13. Uggggggh, one last commit to fix spacing; pushed to Github
  14. Wha? Tests failing? :facepalm: forgot a file again
  15. Commit that file and push one last time for realz
  16. Tests pass, team reviews and approves, we’re good to go
  17. Pull an update of the main branch
  18. Come back to my-sweet-new-feature and rewrite all the commits on top of updated main; group edits into a clean subset of logical changes, one per commit, that makes it look like I wrote the code perfectly the first time, with nicely crafted commit messages that will mean something to some poor future developer that has to maintain my code ten years from now
  19. Run tests to ensure everything still passes; it does
  20. Force push to the pull request, obliterating all those ugly prior commits with these nice clean ones
  21. Try to merge the branch to main with fast-forward only option, forget that Github doesn’t support it (curse you Github! even flipping CodeCommit supports fast-forward only merging)
  22. Fast-forward merge my-sweet-new-feature to main locally so my final commit signatures are preserved
  23. Try to push main to Github, but it fails because the branch is protected
  24. Unprotect main temporarily, repush
  25. Dang it, someone merged new changes since step 17; repull main and rebase my branch
  26. Re-push my final changes and re-protect main

See how easy that is? No excuses moving forward, my friends!

Resolute Comprehension

Resolute Comprehension

I really like New Year’s resolutions. As a lover of habit, the beginning of a year is perfect time to calibrate a new routine. This year I have two resolutions:

  1. Post on this blog at least once per month
  2. Learn a new programming language

The latter was inspired by this article, which is stupidly long but thoroughly enjoyable. As a non-fan of OOP I found myself nodding along quite frequently. He advocates pretty hard for functional languages; while I’m familiar with the paradigm having used it in Python, I haven’t done much with purer forms. In 2022 I intend to change that, probably by learning Clojure.

Erlang and Go are also on my to-learn shortlist, the former for its first-class support for concurrency, the latter because it’s the new hotness for performant APIs.

In other news, I’m working on publishing my first CDK construct, which I’ll share here when it’s ready. I do wish I didn’t have to write it in TypeScript, but sadly I’m at the mercy of the JSII compiler. Why TS doesn’t have first class support for comprehensions boggles my mind. This is the closest I could get:

Array.from(nodeProps.entries()).map(e => new HyperledgerFabricNode(scope, `Node${e[0]}`, e[1]));

Compare that with a Python equivalent:

[HyperledgerFabricNode(scope, f'Node{i}', p) for i, p in nodeProps.enumerate()]

For shame, TypeScript. For shame.

Right On The Nose

Right On The Nose

I’ve been working on a little project here at this blog, one that’s required me to go back and re-read all my old posts. Truth be told tonight I was using it as a distraction from what I really should be doing (backlog grooming ahead of tomorrow’s new sprint).

Let’s just say this post hit a little close to home. I suppose I better press pause for now (but you’ll hear more soon, I promise, and if you’re observant, you might be able to guess what I’m doing).

OOPs I Did It Again

OOPs I Did It Again

Have you ever looked at a heavily object-oriented codebase (Java, I’m looking at you) and immediately felt dumber? Did the design patterns touted as the ultimate in software craftsmanship sound amazing when you studied them in school, but now every time you see them in real projects they result in layer upon layer of confusion?

You are not alone.

There is no one approach to rule them all when it comes to software development, and while I wouldn’t be quite as hard on object-oriented programming as the articles linked above (yes, there are multiple ones), it’s not the only, best, or even appropriate pattern to use in all circumstances.

Don’t Judge Your Book By Its Cover

Don’t Judge Your Book By Its Cover

It’s been said that Vincent Van Gogh didn’t like _The Starry Night_, which is crazy, because it’s one of the world’s most recognizable paintings, and an obvious masterpiece.

If some of history’s greatest artists were unable to judge the value of their work accurately, how much less so are we. Don’t be quick to disparage your creative efforts, no matter how meager they may seem.

Dirty Work

Dirty Work

Developers like to write code, that’s what they do. But being a software professional means working on a number of other tasks, some of which are decidedly un-fun. The wise developer recognizes the importance of these tasks and approaches them with no less effort than their more enjoyable work. Grooming a task list. Writing documentation. Cleaning up repositories. Slogging through a naming refactor to improve consistency. She knows that these will all pay off in the long run.

Yesterday I spent nearly 10 hours working in JIRA, getting my head around nearly 150 tasks that need to get done in the next 3 weeks. Circumstances had forced me to be pretty heads-down in dev-world the past couple months, and my planning responsibilities had fallen by the wayside. I owe the team more than haphazard and vague requirements, and this is the first step to doing better. Here’s to a full July!