Goals for 2022

A collection of scarves knitted by Jeremy Ward.

The end of January is when you’re supposed to start talking about goals for the year, right?

Folks, I think the winter/pandemic doldrums have set in. Since we last left off, I had just completed my reading goal for 2021 and started on Stephen King’s The Gunslinger, which is by all measures a very short book. I’m still reading it in fits and starts.

And you know what? It’s fine. I’ve also been completely heads-down learning the ins-and-outs of the role I took on in September, and having been trying like most of the rest of us to live my life as normally as possible while acknowledging that I just really don’t want to catch the respiratory disease du jour. That means I’ve been spending more time indoors than is typical even for me, and as a result, I just haven’t really had the energy to invest in improving myself.

Honestly, for those who are staying focused and energized throughout all of this, I can’t possibly express just how much I admire you. These last 6 or 7 months have been harder than ever for me, and the one thing I’m learning is just how important it is to set small, achievable goals for myself each and every day. One foot in front of the other, step by step.

Sometime around the time I last wrote in this space, I started craving a hobby – any hobby – that didn’t involve being in front of a screen. I remembered a time when I was little when my grandma gave me a ball of yarn and taught me how to crochet with my fingers. I sat there for hours, making enormous chains of fabric, completely engrossed in the task at hand and losing track of time. I wanted a bit of that feeling again, and I wanted to convert it into a lifelong skill that could be useful both for myself and give me an opportunity to show my friends and family that I think about and care for them. So, I did what all reasonable people do as they near the start of a third year of a worldwide pandemic: I searched for videos about how to knit.

The first website I came across contained an excellent series of videos about how to knit from Sheep and Stitch. Davina, the creator of the site, presents her knitting videos in an incredibly clear and easy to understand way, and the production value of her videos is superb. The how-to series was immediately enough to make me feel confident that I could start knitting right away, and that unlike almost any other hobby I’ve taken on over the years, I could be okay with being terrible at it from the start. Afterall, it’s just yarn, right? If I knit something and it looks bad, I don’t have to give it to anyone, and I will have probably learned a lot from the process.

Friends, let me just tell you that I’m really glad I started to pursue this hobby. Since I started in the fall, I’ve knitted several scarves, most of them with thick, acrylic yarn and your basic garter stitch, just to get a feel for what it’s like. I knitted a coaster, then liked how it turned out, and knitted several more. Then, I purchased the book Knit Stitch: 50 Knit + Purl Patterns by Kristen McDonnell from Studio Knit, and started learning ways to introduce variation to that basic garter stitch. The coasters I was knitting was a nice way to learn a few of these patterns and get something useful out of the process.

In a few months, I’ve acquired a bit of a collection of different knitting needles, tapestry needles, and yarn. Knitting is something I can do for a small amount of time, or for several hours, whenever I feel like I’ve had a rough go at staying on top of all of the things I need to stay on top of while also being regularly aware of that state of things. I’ve even completed a couple of projects to gift to family for milestone birthdays! It’s felt so good to make things for other people that require time, effort, and care again that I’m truly energized by the prospects of improving my skills at this craft.

All of which is to say: I’ve set some goals for this year. They have almost nothing to do with my vocation, but everything to do with re-centering my perspective on being appreciative of the people in my life and on the importance of maintaining a positive mindset of growth.

Here they are:

  • Learn how to knit beanies and socks
  • Finish 15 books
  • Write:
    • 12 blog posts
    • 12 personal journal entries
    • 12 poems
    • Invitations, thank you cards, and letters
  • Create one animated short and compose music for it
  • Finish a personal web or application development project
  • Take more walks and bicycle more
  • Be more:
    • Gracious
    • Kind
    • Generous
    • Willing to help
    • Curious
    • Trusting
    • Considerate
    • Willing to say yes

Some of them aren’t even really goals, they’re intentions. And through the process of setting them, I’ve had some other ideas around what I want to achieve, but it’s too early to write about them right now. What I hope to gain by pursuing these intentions is that ability to get completely lost in the process of creation, because I think that’s gone missing for me for some time now, like a boat’s sail lost in the storm. Thankfully, I’ve landed ashore, taken stock, and am working on finding that direction once again.

It may be 1/12th over already, but let’s make it a great year.

Hey 👋🏼

Chris Lema published a blog post at the beginning of this month entitled Stop Making Premature Announcements that really resonated with me. I can’t count the number of times in my life I’ve said to someone else, “I’m going to,” “I plan to,” “I want to,” and so on only to realize weeks or months later that I lost interest or focus or drive on the thing I planned, wanted, or was going to do that I simply never saw through to the finish.

It’s far better to be able to proclaim “I did it,” “I built it,” “I created it,” or “I finished it, here it is!”

That post was written in October, and I published my last post at the beginning of August. In that post, I declared that I’m open for business. On September 1st, I began a new Senior Software Engineer role where most of my energy during the day has kept me focus on meeting new people, learning how to work together, figuring out what we’re working on (and how to work on it), and simply getting up to speed like everyone must when they start with a new company.

Two things are certain: I’m loving the challenges, and between everything I’m juggling during the day and the still ever-present state of the world, I’ve just been far too mentally exhausted by the end of the day to accomplish much else.

At the start of the year, I set extremely modest goals for myself. I wanted to keep things light. As light as possible. With everything that’s been going on in the world, from the pandemic to the climate (regular and political) to the struggles everyone has been facing, some far more disproportionately than others, maintaining an upbeat attitude while surviving alone feel like enough of an accomplishment alone. Admittedly, I haven’t been eager to add a set of goals to that load.

With that laid out, this is going to feel so small. I recognize how small it is, how insignificant. But, in this year, in these times, with everything else going on, and how difficult it has been for me to maintain extra motivation and allocate time for creativity, learning, and exploration, I accomplished something I set out to do this year, and I want to tell you about it.

I accomplished my goal of completing 15 books this year.

See? It’s nothing. The effort was full of stops and starts all year long, and the majority of the books I finished I started reading sometime after June. Some of them were technical books, including one that I read as part of the Dev Book Club during the spring, and some were fast, easy reads. But, the important thing is that I set out to do something, I did it, and now I’m telling you about it. And the great thing is, it’s still October, I can still read the rest of the year, and still feel proud that I accomplished something so small.

Here are the books I’ve finished in 2021:

  1. Building GitHub Actions by Michael Heap
  2. The Beautiful Struggle by Ta-Nehisi Coates
  3. Refactoring by Martin Fowler
  4. The First Bad Man: A Novel by Miranda July
  5. She Memes Well by Quinta Brunson
  6. Breath by James Nestor
  7. Big Magic by Elizabeth Gilbert
  8. Node.js Web Development by David Herron
  9. You are a Badass at Making Money by Jen Sincero
  10. Year of Yes by Shonda Rhimes
  11. Little Weirds by Jenny Slate
  12. St. Paul by William Lindeke
  13. Exploded View by Sam McPheeters
  14. Based on a True Story by Norm Macdonald
  15. Kafka on the Shore by Haruki Murakami
  16. Humblebrag: The Art of False Modesty by Harris Wittels

I’m currently reading The Gunslinger, the first book in The Dark Tower series by Steven King. 11/22/63 and Under the Dome are two of my favorite novels I’ve read to date, and I’m looking forward into digging into this expansive series. Maybe I’ll even finish it! You won’t hear about it again until I do.

Anyway, I’ve been wanting to write this post for awhile, but I haven’t known how to put things into words. I’m glad I finally did. I hope to do so again soon, but I promise it won’t happen until I’ve accomplished something.

Thanks for reading. I hope you’ve been well.

Open for Business

Over the weekend, I read Big Magic by Elizabeth Gilbert, the best-selling author of Eat Pray Love. It was loaned to me by my partner, Abby, who set it on the coffee table and left a Post-It note that read “Follow your curiosity…” stuck to page 235. Recognizing it as the act of love that it was, I started from the beginning and read it straight through to the end of the course of two days. I’m so glad I did.

The central idea in Gilbert’s book is that living a creative life is a choice we each make. She suggests that ideas are ethereal, and that they come to those who are ready to accept them and work to bring them into existence. We can choose to listen for these ideas – they are quiet, almost faint, and often are not immediately clear – or we can let them go, and they’ll find someone else willing to see them through. Ignore ideas long enough, and they will stop coming to you.

I used to live a creative life. Or, I suppose as the late Mitch Hedberg might say, “I still do, but I used to, too.”

Growing up, I passed the time by drawing cartoons, usually as a way to entertain my friends. My favorite illustration-based storytellers were Bill Watterson, Gary Larson, Berkeley Breathed, Mike Judge, Matt Groening, and Bill Plympton. I carried around with me a notebook where I’d put what I thought were my best ideas into it, and slowly built up a little catalog of quickly drawn cartoons paired with terrible puns.

I started working at a fast food restaurant the summer before my 16th birthday. Two summers later, I hadn’t saved up much, but managed to convince a co-worker to loan me enough money to purchase a drum set. It took me over a year to pay her back in full, and by the end of that year, I’d started playing drums with other musicians, and pursued that creative path for quite some time after. I played in a lot of different bands, and through the years, I designed stickers and t-shirts and illustrated numerous record covers and show posters.

It was during that time that I purchased the Complete Idiot’s Guide to Creating a Web Page & Blog, and started teaching myself about web development.

In the subsequent years, I built simple static sites for myself and my friends’ bands, as well as my first ever site for a small business. I never pursued the practice as a full-time thing – I enjoyed doing it too much in my free-time over nights and weekends, slowly building up a catalog of knowledge and being able to achieve more and more.

In 2011, I enrolled in an Associate of Applied Science program at my local community college. During that time, I wasn’t actively playing in a band, but I was renting out a practice space near Downtown Minneapolis so I had some place to go to play drums. I bought a desktop computer and put it in that space so that I could also continue to work on my programming skills. I took that time to explore creative writing in the form of poetry and occasional prose, and I did a redesign on this website that included some of that poetry and my illustration.

Two years later, I began my first web development internship. After I graduated in May of that year, I was given the opportunity to work full-time at that same agency and have been generally working in that exact same space ever since: agency WordPress development with a dash of Shopify.

By 2017, my partner and I bought our first home. I had just quit my last band a few months prior, and before we moved, I gave my (second) drum set away to my friend and former bandmate Matt. I felt that I was done playing music, and couldn’t bear the thought of having a drum set just sitting up in storage, and we didn’t have much room for it anyway (not to mention our neighbors probably wouldn’t take terribly kindly to me bashing away at the kit).

From that time until now, the only constant has computer programming. My focus narrowed to primarily back-end development upon joining an agency that worked with larger corporate clients, and as I mentioned in my last post, I’ve felt more or less like I’ve been treading water since then. I still draw, but not seriously. I still make music, but haven’t committed myself to it. I still write code, but it’d been so narrowly focused at work that my hunger for more has largely been dependent on my energy levels at the end of the day and on weekends.

It’s possible only my friends have read about any of this on my blog, since I changed the focus to only the computer programming aspect some time ago. I still intend to keep that focus here, but as of today, and in the spirit of Elizabeth Gilbert and with much thanks to my beloved partner, I am taking active steps to reclaim my time and my creative life.

I am a musician.

I am an illustrator.

I am a poet.

I am a computer programmer.

I am a business owner.

I’m still working on the next phase of my career, but one thing that is clear is that I want to get back to working on interesting projects. I want to help people who are struggling to reach an audience over the internet to build their platforms and give them a voice. I want to build meaningful relationships and empower others to be able to express their own creative voice by creating and assembling the tools that they need to achieve that.

If you’re working on a project or are just getting started with a new idea, and you need technical expertise, I can help. At this time, I’m open to taking on projects involving full website builds, custom plugin or application development, or website upkeep and maintenance. My primary experience centers around WordPress, but if you need help building a Shopify site, or you already have or want to build a web application in another language such as PHP, Python, Node, or Go, I’m most interested in these new challenges and will work with you to help you create your vision on top of these platforms using industry-standard frameworks, practices, and tools.

Interested in working together? Then let’s talk.

Resources

Thanks once again to my wonderful partner Abby for helping me recognize my path back to a creative life, and for all of her love and support over the years.

You can learn more about Big Magic at Elizabeth Gilbert’s website:

If you have a Spotify membership, you can listen hear me play drums via this playlist:
(edit: removed. I canceled my Spotify subscription in favor of Tidal)

Here’s an illustration I posted on this website several years ago, drawn on an iPad:

Here’s an animated GIF I made from photos I took at the Minnesota State Fair in 2013:

Finally, I republished one poem I wrote in 2011, entitled Waiting.


I’ve learned this weekend that it doesn’t matter whether any of this is any good. What matters is that I continue to create. I’ll leave it to the rest of you to love, hate, or feel nothing at all about any of it. This time is all we get. Thanks for reading.

Past, Present, and Future

When was the last time you’ve sat down and thought about your career? Do you like what you do? Are you getting what you want out of it? Does it challenge you in ways you want to be challenged? Are you thriving, or simply surviving?

I love writing code. If you’ve read this blog for any length of time, you know that I’ve worked primarily in the WordPress space for the last 8 1/2 years, and that I’ve simultaneously kept my feet firmly planted in the broader developer communities. I’ve done this because I feel that it’s important to get a full range of perspectives to inform my craft, and to determine whether there’s something someone is saying from outside of WordPress that could help improve the way we do things within it. I love writing code, and I’m also passionate about software architecture and finding ways to reduce the friction involved in maintaining code. This is a big reason why I’ve focused my attention over the years on concepts like modular development, the five principles of S.O.L.I.D., writing clean code, incoporating testing into your workflow, etc.

I write about these topics here not because I think of myself as an expert in any of them, but because I find them interesting and I think that by discussing the way in which we write code, we can start to consider whether how we write it today is serving us both now and in the future. How difficult is it to change your existing codebase because of some design decision you made in the past, because you didn’t write tests to support it, or because you didn’t document it, or perhaps all three and you’re maintaining a codebase that wasn’t even written by you?

There’s a lot of friction in writing software. In my experience, that friction is lessened over time through coding practices such as code review and pair programming, particularly on small teams, because those are the times in which we can discuss our craft and the current state of our projects, share ideas, and come to consensus about the way in which we want to do things going forward. No two people have the same pool of knowledge, and only by encouraging these practices do teams, over time, grow together to understand the existing state of their codebase and agree upon a vision in which they want it to evolve.

There’s also friction in change. Just think about how passionately people have been opposed to the WordPress block editor! It’s come a long way since it was first released a few years ago, and what I think is most exciting about the project is more willingness to make drastic changes to the way we do things: the chance to try something new and break out of the status quo.

As a fan of PHP, I wish that same mentality transferred to the server-side language. In early 2019, WordPress bumped the minimum required version of PHP from 5.3 to 5.6, and stated as a goal that it was aiming for 7+ as a minimum by the end of that year. Around the same time, there was also some discussion about how we could now, finally, start to incorporate some modern syntax into the core application. Two years later, the same minimum version and much of the ways we write PHP in WordPress remains the same.

Going Forward

All of this is a long way of saying that there is a lot of momentum and focus on JavaScript: not just in WordPress, but everywhere. I need to acknowledge that momentum, accept change myself, and determine what all of this means for me.

At the start of my career, I worked on a broad range of projects, building full sites atop WordPress and Shopify for small businesses and non-profits. I enjoyed this work because it exposed me to a variety of technologies and I was learning something new nearly every day. I collaborated directly with designers and my clients to help meet their visions, and when my projects were finished, I got to launch them for the world to see and use. In fact, just two weekends ago, my partner’s aunt told me that she visited the Glensheen Museum in Duluth, purchasing tickets via the site I built several years ago during my time at a previous agency.

For the last 4 1/2 years, I migrated into plugin development, both at agencies and on the product side. I still learned a lot, and in fact, learned so much from one client in particular that it helped further shape my curiosity and interest in the software development lifecycle and software architecture in general. But, due to the nature of the kinds of projects I worked on, I rarely got to build something that I could celebrate and share with others. I’ve felt further and further isolated from the advancements in WordPress, few of which have come to the language in which I’ve specialized.

I have been only surviving, not thriving.

Last spring, I began studying Python with the goal of landing an engineering role outside of my comfort zone. Interviewing was going really well, but then the pandemic hit, and hiring ceased. This summer, I am continuing my Python exploration, brushing up on Node.js and React, getting better at understanding Docker, digging deeper into CLI scripting, refactoring some existing projects and thinking up new ones. I attended DevOpsDays Minneapolis (online) and was completely in over my head with terminology and concepts I have had virtually no exposure to during my time in WordPress, and I loved every minute of it.

I am motivated to get back to the time when working on projects was delightful; when I could launch something new and show it off to my friends and family. I want to write modern code, to collaborate with my peers, discuss pros and cons of various architectural approaches, and create beautiful, well-tested, and stable applications. And I hope to do so at a company, like so many companies that I have already worked for, who value a positive and supportive engineering culture.

I know I can get there. Perhaps it could be with you? If you or your company is hiring and you think I might be a fit, then I’d love to chat. Please get in touch.

Two Algorithms Go To a Foo Bar

A friend and I were having a really interesting discussion this week about PHP foreach loops, array_* functions, and the subjectivity around code readability; significantly interesting enough, in my view, that I wanted to document it here and share it with my broader network for consideration and discussion.

Let’s say you have an array of options you’ve assigned to a class property:

$this->options = [
    [
        'text => 'Good',
        'value' => 'the-good-one',
    ],
    [
        'text' => 'Better',
        'value' => 'the-better-one',
    ],
    [
        'text' => 'Best',
        'value' => 'the-best-one',
    ],
];

This array gets used in a system to select a default option for the list. The calling code searches within the array to see whether there is a match, and if there is, it returns the value of that match. So, for instance, if I passed the string the-good-one to my search lookup, I would get the-good-one back.

If someone wanted to get the value using the text key, the same behavior applies: I pass in Good, and once again, I get the-good-one back. If, then, I pass in something that’s not located within the array, I simply get back the value I passed in – the-worst-one or Worst would return the-worst-one or Worst, respectively.

You’re assigned with writing a fuction that performs these steps. How do you solve it?

The Loop Approach

One possible algorithm for finding a matching value in this set is to use a loop. It might look something like this:

public function get_matching_option_by_value_or_text( $value ) {
    foreach ( $this->options as $option ) {
        if ( $option['value'] === $value ) {
            return $value;
        }
    }

    foreach ( $this->options as $option ) {
        if ( $option['text'] === $value ) {
            return $option['value'];
        }
    }

    return $value;
}

Loops are one of the first programming control structures that new developers learn, and they can help make solving these kinds of problems easy, but they are not without their tradeoffs. Though simple, this example does contain some inherent complexity, primarily: 1) moderate nesting of control flow, and 2) clear-ish but not necessarily full clarity of developer intent (reading the code, you have to stop and consider why there is a return statement within the loop).

The complexity here is that the main point of the algorithm is to determine if a given value doesn’t exist in the value index, and find the matching value for it if it does exist in a text index.

Let’s look at an alternative using built-in PHP array methods.

The PHP array_* Approach

The same result using a loop control flow can be achieved with two built-in PHP array methods: array_search and array_column. The array_search method returns the index of the found result or false if the result could not be found, and array_column pulls all of the values out of an array into a flat structure, preserving the keys. Let’s take a look:

public function get_matching_option_by_value_or_text( $value ) {
    $value_index = array_search( $value, array_column( $this->options, 'value' ) );

    if ( false !== $value_index ) {
        return $value;
    }

    $text_index = array_search( $value, array_column( $this->options, 'text' ) );

    if ( false !== $text_index ) {
        return $this->options[ $text_index ]['value'];
    }

    return $value;
}

There is both more and less complexity in this approach: more because there are two methods within the algorithm that fewer developers might be familiar with, and because we’re making some nested inline function calls (e.g., calling array_column as the second parameter to array_search). It also has more variable assignments, once because we want to know if we found the index of the value key, and again because we want to know if we found the index of the text key.

That said, at the same time, there is also less complexity, because the control flow is subjectively easier to follow: I simply need to read top to bottom to understand what’s happening, and if I need context around the specific functions being used, I can read the PHP documentation to understand how those functions work. In plain language, I can see “If there is a value index, return the value that matches it from the options. If there is a text index, return the value that matches it from the options. Otherwise, return the value.” The intent behind this approach, I’d argue, is clearer, because any questions that get raised as a result of the algorithm can be reviewed within the documentation, whereas questions about the first approach might need to get answered by running the code and stepping through it with a debugger, or asking the original developer who wrote it.

Programming “The Right Way”

Spoiler alert: there is no “right” way. The beauty of programming is that there are lots of different ways to tackle problems. To me, the most important thing is that when someone is assigned at some future date to modify code you’ve written in the past, how easy is it for them to understand what you’ve written? In my view, it’s easier to follow control flows that have reduced levels of nesting, and which use native language contructs. However, I’m just one person, with one worldview, and one collection of knowledge. Everyone’s technical level and programming approaches differ, so it’s important not to be dogmatic about a particular approach, and appreciate that broader audiences might understand how things work in a different way.

At the end of the day, the one true measure of your algorithms is how many tests are supporting it, so that you can more confidently and easily change it when the tides shift. :)

Addendum

I edited this post after a conversation with another friend, Sal Ferrarello, as I’d realized the original examples for the loop were incorrect. Both the loop and array_search examples have been revised to be the same: returning the $value if it was found in the 'value' index of the original array, otherwise returning the 'value' index if $value was found in the 'text' index. Finally, the methods both return the $value parameter if it was not returned in either search. Thank you, Sal, for noticing the inconsistencies in the original post.

There are, also, notably some limitations with array_column in PHP, which does in fact make the loop example preferable. The array_column method creates a new array from the values, so if any does not contain that index, the indexes of the new array will not match the one of the $options array. Thus, it would seem, once again, that the simpler approach, even with its additional “grok-factor” (because of the early returns in a loop), might in fact be the superior one.