It was quick because Bekki, having met him more than once, already knew he was for us. She’d been eyeing candidates for adoption online and occasionally visiting them, and she had gone to meet Rascal the day before Thanksgiving. By then nearly all my belongings had migrated to our house in Bloomington, but I was still living out my last few weeks in Washington Heights. Until the end of January we knew we’d be at home together for one week, in Germany together for three, and apart for another three while I was away for a conference and for work. Sweet as my trusted source assured me Rascal was, we knew we couldn’t take him. Not quite yet.
When someone else did, we figured that was that. But here he was again. So it came to pass that we were able to go together to see Baloo (as he was now called) and to learn as much of his story as the shelter could tell us. He had been brought in by a family who purchased him on Craigslist but didn’t have time; adopted by a young couple who returned him after three weeks due to a family member’s allergies; adopted by another young couple who returned him after three days due to his nonstop vomiting; and here we were, another young couple. We liked him and we thought we’d like to adopt him, but we didn’t want to continue the pattern, so we went home and slept on it. The following day we knew not only that his troubles endeared him to us more, but also that we were ready for whatever they might be, whatever he might need us to do.
His first days with us were quiet and loving, when they weren’t vomitorious. Some combination of politeness and hunger impelled him to try to clean up his own messes, which we quickly put a stop to. Dozens of carpet-bombings and a couple medical inspections later, we’re slowly getting the hang of managing his stomach, he’s getting more comfortable with us and otherwise, and we’re starting to discover hints of a boisterous personality. Bekki got home from driving me to the airport to find that the dog had amused himself in our several hours’ absence by reorganizing the house a bit. And that’s how we realized that was the longest we’ve left him home alone. Is this 10-year-old fellow’s apparent gentility with his feline and human housemates a façade? I’m away from the home office till mid-March, so we’re about to find out.
His new name was Bekki’s idea: he responded well to “Rascal”, he’s husky-derived, and one of his new owners is a programmer. Haskell. It’s even more fitting because we lazily evaluated his name just in time to tell the vet. Now I have two Haskells to get to know. For the moment, I’m focusing on the 65-pound wannabe lapdog who wishes I’d walk faster, then cuddle more.
For the last two and a half years, ever since Bekki started her Ph.D. program, I’ve been splitting my time between New York and Indiana. At first, as part of a larger group expected to work together from the New York office on Tuesdays and Thursdays, I could at best fly out on a Thursday evening, work remotely Friday and Monday, and fly back Monday night. After a year of that, I transferred (along with my product and team) to another group in order for us to be better managed, which had the pleasant side effect of enabling me to stay and work from Bloomington for stints of a week or longer.
Another side effect of a steady diet of lighter travel and enlightened management was that by the time 2013 rolled around, I realized I was mentally ready to prioritize my health. If you were to guess that getting healthier might be accompanied by other improvements, you’d be right. I celebrated my 35th birthday yesterday, so I’m of a mind to reflect on some ways in which 2013 went well for me and how I intend to build on each in 2014.
I hoped — but initially didn’t quite believe — that I was prioritizing my health. I treated my weight loss as a project to be managed. Other than assigning arbitrarily fixed scope (“lose 45 pounds”) and fixed deadline (“in a year”), I managed it with an Agile-influenced self-designed process that helped me make the daily choices I wanted to make, radiated current status visually at home and at work, prompted me to periodically review progress, and incremented itself one simplest-change-that-could-possibly-help(-and-stick) at a time.
As is typical when the stated goal and the stated deadline are both “fixed”, one must be prepared in the end to adjust the goal. I didn’t lose 45 pounds. But because the parameters were of my own invention, I don’t feel disappointed in the least about the project. Rather the contrary: I’m nearly 30 pounds lighter than a year ago, I feel and look more like myself, and I’ve managed to convince myself that I really have been prioritizing my health.
For 2014, now that I trust what I’ve been doing, I’m willing to make more significant lifestyle changes.
I restored this site to operation and wrote 22 articles. You won’t be surprised that my two most frequent topics were (1) health and (2) Test-Driven Development.
I was surprised to have written so much. In 2014 I’ll make a point of delivering no fewer than 26 articles, no less often than every two weeks.
One of the TDD-related articles was from my talk at pkgsrcCon in Berlin. As a longtime member of
pkgsrc-pmc, the steering committee for the pkgsrc package management system, I have long felt the need to demonstrate technical leadership by improving the architecture of the system. I plan to attend this summer’s pkgsrcCon in London; I hope by then I’ve done more than merely maintain my packages, and can show some consequential improvements to pkgsrc internals.
I was elected to the Board of the NetBSD Foundation. In 2013, I learned what the board does and how it does it, and represented NetBSD and pkgsrc in two interviews. If health was last year’s top priority for me, NetBSD is this year’s.
I’ve been serving for several years on the Board of the Philolexian Foundation, which supports the operation and strivings of the Philolexian Society of Columbia University. This year I ascended to President. I also took inspiration from my frequent proximity to Indiana University to write and perform a reasonably bad poem at Philo’s annual Alfred Joyce Kilmer Memorial Bad Poetry Contest.
Two of the articles featuring Test-Driven Development were about ikiwiki, web content management software I’ve used to solve publishing problems for NetBSD and Philolexian. Before 2014 is out, I’ll finally be publishing this site with ikiwiki too.
Another of the Test-Driven Development articles reflected my deepened understanding that TDD is a technique for learning rapidly what’s going on in code, even (maybe especially) when one doesn’t know the language well. I figured that out because a workshop at CodeMash 2013 pleasantly forced me to. CodeMash was the first software development conference I ever attended and the first of three in 2013. The third was Software Craftsmanship North America, where I experienced my first Code Retreat and the long-absent, much-needed feeling of being among peers whose software values matched mine.
In 2014 I intend to spend much less time with people who don’t care about what I care about, and much more time with people who do.
The other conference I attended last year (as a newly minted Certified Scrum Professional) was Scrum Gathering Las Vegas. Thirty of my most valuable 2013 minutes were spent at the SGLAS Coaches’ Clinic talking with Roger Brown. Considering coaching as a career, I wanted a coach to help me understand more precisely what that looks like and whether I might be able to do it well. Roger’s answers to my questions about the coaching life fit my mental model — and when I answered his questions, his reactions indicated that I’d be smart to try it.
Another thirty of my most valuable 2013 minutes were spent at the New York office talking with a senior manager. I shared with him my desire to coach, the potential benefits to the company, and my need to validate the idea. He knew of a team looking for some coaching and sent me to Montreal to coach them.
For a total of five days surrounding Thanksgiving with the family in New York, I worked on-site with the team as a whole and individually, developers and managers, hands-on and nonstop, and it was exhausting and exhilarating. My brief time with that team validated for me that I was already pretty decent at coaching, that I could be great at it, that it might let me make a small dent in the universe, and that I loved it.
In 2013 I determined that I needed to feel greater appreciation for my work, that I was willing to identify and deliver more valuable work in order to get it, and that helping teams make better decisions about software development would be highly valuable.
In 2014 I expect my responsibilities to change from managing a single product to coaching multiple teams, and I expect my efforts to produce observably meaningful results for all involved.
A year ago the fact of living in New York wasn’t the bottleneck to improving my health. A few minimal effective changes later, I feel otherwise. I’m doing well; to do better, I need to be able to safely ride my bike on pleasant paths without shlepping it up and down three flights of stairs, to randomly drop by a tennis or basketball court and probably get to play, to comfortably house some sort of dog (preferably large) who requires lots of walks, to relax in a quiet home, and to travel less.
My team isn’t — indeed, most of the company’s development teams aren’t — in New York. So continuing to live there wouldn’t win me much effectiveness or save me much travel. If I were to split my time such that my periodic trips were to the New York office, the proportions would be quantitatively different, but the arrangement wouldn’t be qualitatively different.
My life isn’t in New York. To a midwesterner by temperament, it never could have been. I’m grateful for eight and a half formative years there, and I’ll be happy to see it every time I visit, but New York was only ever a place I tolerated in order to get what I needed.
Everything I need now is in Bloomington.
When I think about how I spent my 35th solar orbit, I feel anything is possible in the next one. I feel powerful. More than ever I know who I am, who’s for me, and who I’m for.
I first learned of the existence of a composer named Nikolai Medtner fourteen years ago, when overworked Amazon robots advised me, having peered deeply into my purchase history, that the missing je ne sais quoi in my Shopping Cart was a $60 box set of his complete piano sonatas. An ambitious suggestion, to be sure. I was nonplussed. But I became willing to plus it when I spotted that the pianist was Marc-André Hamelin, whose existence I had already discovered and come to appreciate. Anything Hamelin wanted to record, I wanted to hear.
Medtner’s music did not endear itself to me immediately. But when it did, it began slowly and persistently altering my life choices. I am now a person who eight and a half years ago moved to New York to find my way back to music. I am now a person who agreed to perform in recital for the first time since high school because it meant an opportunity to share my love of Medtner. I am now a person who composed a small piano piece (under the stylistic influence of Medtner) in order to prove to myself that I had what it takes to write worthwhile music. I am now a person who graduated college with a degree in music, who expects my musical training to continue, my musical life to flourish.
After all these years, I found myself last night in a room (Zankel Hall at Carnegie Hall) in which I saw for the first time my favorite pianist playing my favorite composer. The time and place of this culminating event were themselves, to me, poetic. And it’s fitting that Hamelin’s recital led to a new and timely insight about why Medtner’s music so resonates with me: his extraordinary musical intelligence never — unlike plenty of self-consciously clever composers — draws attention to itself. It is only, always, ever subservient to the physical and emotional experiences he designed coterminously for the pianist and the audience. I asked my sister afterward whether she’d noticed that an entire movement had been in an unusual time signature (15/8). She had not, because the movement had not been written in order to be noticed for its cleverness. Medtner himself would probably say it was written that way because that’s how it needed to sound, that he subjectively and with great care divined the natural shape it needed to have, then worked hard to preserve and develop it to its fullest expression.
With renewed vigor over the past year, I’ve been doing the same for myself, reevaluating the various ways in which I choose to spend my skill, ability, and effort, seeking to minimize waste and maximize returns. Several slow-building changes are close to fruition, one particularly so as I write these words. I’m excited to tell you more soon.
In classical sonata form, two themes of contrasting character battle for primacy, then reconcile. Medtner’s chief contribution to sonata form is his novel route to reconciliation: he brings his themes together in time. By arranging for us to hear them simultaneously, he shows his seemingly incongruous motifs to be thematically related and contrapuntally complementary. Each theme demonstrates its value in isolation and opposition, they take turns developing, and in the end it turns out that not only can they coexist, but also in so doing they deepen each other. These profound syntheses in Medtner’s sonatas, with their hard-earned simplicity, are for me some of the most intellectually and emotionally thrilling moments to be had in music and, as such, in all of existence.
Medtner’s been leading me by example all along. Fourteen years and it took me until last night to see it. To harmonize two themes, identify their common ancestry, then play them together. The denouement has to be earned; it’s hard. Until, at long last, it finally becomes simple.
Some commonly held ideas about what a programmer needs in order to learn another programming language:
- Your motivation: have a real problem you need to solve
- Your patience: tolerate solving it slowly
- The language’s design and basic use: read a book
- The language’s standard libraries: consult online docs as needed
- The language’s actual behavior: play with the REPL
- Your basic understanding of the language: repeat all of the above until you’ve solved the problem
- Your progressively improved understanding of the language: repeat for several more problems
I find step 6 fuzzy. When you don’t know a language very well, you can’t express yourself in it very well, and your code frequently won’t do what you intend. Of course, you can’t debug it very well either, so you’re forced to context-switch — either to the REPL (assuming there is one and its behavior is sufficiently representative) to validate your uninformed guesses about what might be wrong, or by littering
printf statements everywhere. Neither makes for a fast feedback loop.
We all contend that context-switching and slow feedback loops are inefficient when we’re learning how to solve problems in languages we already “know”. So why do we seem to tolerate these inefficiencies when we’re learning how to solve problems in languages we “don’t know”?
A personal anecdatum
At CodeMash a year ago, I attended an afternoon workshop on elements of advanced Ruby style that explicitly targeted experienced Rubyists. My experience consisted of having attended an intro-to-Ruby workshop that very morning. Unsurprisingly, I had trouble keeping up with the first couple exercises, and started to wonder whether I’d get to have fun or learn much.
I took a moment to retrospect. Where was the bottleneck? Was I slower than others at noticing when my program produced the wrong results? Probably not. Was I producing many more wrong results before arriving at the right ones? Almost certainly. So if I was going to have a productive afternoon — first by keeping up, and then maybe enjoying myself and digging deeper — I needed to manufacture an advantage.
I will turn this car around
As I worked on each new exercise, I whittled away a bit more at my bottleneck. First, I figured out how to load my class from a driver program. Then I mapped a
vim key to save both files and invoke the driver. Then I replaced the class’s verbose status reporting with some assertions in the driver, comparing some expecteds to actuals. Then I only displayed assertions when they failed.
I had turned the tide. I had made myself able, just barely, to complete each exercise in the time allotted. This would be a productive afternoon after all.
Deep breath, and continue
I extracted each assertion into its own method, to remind me of its meaning at a glance, and so I could easily comment it out when I was visually confused by too many assertions failing. Then I factored out the common bits of state shared by multiple assertions, so that I could more quickly write new assertions without screwing up. Then I started writing assertions first, at the beginning of the exercise, and making sure they failed correctly before proceeding.
The workshop’s exercises were cleverly designed to scale to each participant’s needs. At this point I was completing not only the simplest form of each exercise, but also each of the successively harder forms, and then turning to help my neighbor.
You see what I did there
Dear reader, from this narrative you have doubtless identified the catalyst for my rapid learning of a new programming language: Test-Driven Development. You may not be surprised. I was! Even as a longtime TDD adherent, I had assumed the steps to professional competence in a language were:
- Do whatever you do to learn enough of the language
- Find and master a popular TDD tool
- Test-drive production-quality code
On the basis of my experience, I now believe it is more efficient to replace the first step with these two:
- Figure out just enough of the language to express runtime assertions from outside your application code
- Test-drive in order to learn the language faster
You don’t need a fancy tool to apply TDD concepts. You might want TDD concepts to accelerate your learning — even when what you’re learning is a new programming language.
Schmonzcast #16: Like last year, I gave a lightning talk at this year’s CodeMash. Unlike last year, I didn’t prepare any speaking notes, just basic bullet-point slides — and to hear how I sound without rehearsing the talk at all, I didn’t rehearse the talk at all. I was hoping for “more relaxed” without too much “less polished”; I wound up with some of both. Somehow it added up to the allotted six minutes (or watch on YouTube), down to the second. This rapidly-congealed, never-practiced short talk is not profoundly great, but I bet the roomful of programmers found the content reasonably interesting, and I know it was good for me to practice a looser approach to public speaking.