This week I ran a workshop. Last week I was in one.
For as long as I can remember, and probably longer, I’ve had a self-directed drive to learn, strong enough to be salient to observers. Lately I’ve become aware that I also have a periodic need for tiny doses of structured learning. Last week made this the third consecutive year I’ve taken some kind of training course. I observed the new pattern when I added James Grenning’s TDD for Embedded C to my résumé and realized that if a recruiter or hiring manager saw nothing but the top three “Education” items, they’d get a remarkably accurate impression of me. I coach, I lead, I Agile, I solve problems, and I test-drive my code.
But not totally accurate. I don’t C.
Not much, anyway. I can think of a total of four bits of code I’ve ever written in C:
- A program to generate the Fibonacci sequence (iteratively and then recursively)
- A JNI library allowing Java programs to create a “link” (symlink on UNIX, shortcut on Windows)
casestatement in the NetBSD/macppc bootloader to allow system administrators to configure kernel behaviors (just like they already could on NetBSD/i386)
forloop that instructs ikiwiki, when run as a post-commit hook in a website repository, to do nothing whatsoever when the triggering event was a
cvs add <directory>(because that acts immediately on the repo, does not constitute a commit, and justifiably confuses ikiwiki if not filtered out)
I’m pretty sure that’s everything.
What I hoped for
Last week’s course was designed for people who’ve been developing for embedded systems in C to become acquainted with Test-Driven Development in general and/or in that context. I, on the other hand, am very comfortable test-driving and I wanted to become better acquainted with C. I knew I wasn’t in the course’s target (ha!) audience — but I also knew that someone skilled with TDD can exploit its fast feedback to learn a programming language quite quickly.
With this in mind, I signed up for the course as an act of self-engineering designed to focus 3 days x 5 hours of my attention on the material I wanted to be learning. And I enlisted a pair partner to help me stay focused and un-stuck.
What I did
During exercises, my remote pair and I used Screenhero to share screen, mouse, keyboard, and voice. We didn’t use any particular pairing style, other than a little ping-pong to get rolling. My pair had written some C++ somewhat recently, and often had better guesses than mine about how to say our next idea in C. We both understood when and how to test our guesses as quickly as possible.
During the TDD lectures, we each muted our Screenhero to avoid echoing the incoming audio at each other. I generally continued working on the day’s exercise. Sometimes my pair would join me. Without sound, I’d wiggle my mouse cursor (Screenhero gives each user their own cursor) to indicate I wanted the keyboard.
Because my pair and I had similar levels of skill with TDD (good), C (meh), and pairing itself (good), I didn’t notice silence slowing our pace much. I did, however, notice it constraining the flow of humor.
Each evening, since we hadn’t gotten all the way down the exercise’s test list, I’d continue working (solo) until we had. The following morning, I’d review with my pair.
We’d been doing the training exercises online in Cyber-Dojo, which is very convenient for getting started, especially when the instructor provides ready-made exercises with test-driven supporting code and well-thought-out test lists, along with all the needed tools. Once the course was over, I knew that to sustain my momentum, I’d need to be able to edit, build, and run tests in my usual development machine — and pronto. The day after the course, I created a local git repository, added all three exercises as we’d done them, installed CppUTest, debugged the exercise builds on my particular host OS and compiler, and committed the fixes to
makefiles and code to make the tests green. Then I dumped the next few things I know I want to try, in a sensible order, to a to-do list.
Now that I can run the tests from my usual editor with my usual keystroke, and won’t forget my next goal, I’m confident that my learning will continue.
What I got
I wanted to learn some C. I got what I wanted.
I also got geek joy. When we figured out just enough about bitwise logical operators to test the right thing, make it pass, then refactor to more expressive symbols, that was a programmer’s high. I’ve always wanted to understand this stuff. Given a goal, a fast feedback loop, and a pair, I was able to start understanding it.
The joy was greater because it was shared. Usually I’d consider it risky to pair remotely for three days with someone I’d never met. But if that pair is someone who works for Pillar and thinks learning about TDD in C sounds awesome? I had no doubt in my mind we were gonna have a good time together, and we did.
Some of the joy was meta-joy. Since TDD is a great way to learn design and domain concepts, and I’ve used it to learn one programming language, I hypothesized that it might be a great way to learn another, and that sure feels true. I love it when a mental model holds up!
I’m also feeling joy in my self-mastery: knowing what I wanted to learn, knowing what I needed to start and continue learning it, and arranging to get what I needed. (I talked about when and how I learn, among other things, on this week’s Developer on Fire. I’d love to hear what you think.) And getting better in general at knowing what I want — like spending more of my time programming — and arranging to get it.
There’s a particular refactoring direction I want to take one of the exercises. If it works out the way I hope, I’ll learn some C. If it doesn’t, I’ll learn some C.
We didn’t get to deploy to hardware. I’ve got a Raspberry Pi and an Arduino, never used. I’d like to test-drive a “Hello World” and see it run, then test-drive the basic use of a device-specific hardware feature and see it work. That’ll teach me some embedded basics. Once I’ve done that, I’ll have a better idea what I need to learn next.
Many NetBSD kernel drivers can be recompiled, with no source changes, into standalone userland programs. (See also rump kernels.) This means test failures can crash the process, but never the kernel — so automated test suites can be run freely and frequently, and it might be possible and sensible to test-drive new functionality into the NetBSD kernel. I’d like to try. Maybe I’m closer than I think.
What I’ve been up to
I’ve done very little writing lately. If it weren’t for my guest appearances on other shows, I’d be doing zero podcasting. I’ve been traveling frequently for work and a whole bunch of conferences while effortfully maintaining new food and exercise habits. That’s all I’ve had time for.
After this week’s Path to Agility conference, I’ll be traveling less and working from home more. I expect to be writing regularly again, starting now. Since I’ve been speaking regularly, I’ve been incrementally improving how I present and publish. And since I’m about to take a break from conferences, here’s what I’ve figured out so far.
Notice CFPs of interest
”CFP” == Call For Proposals. Or sometimes Papers, but I haven’t written any of those, and am intimidated by the title.
I mainly become aware of conferences when someone I follow on Twitter mentions them, or sometimes when someone I meet in person recommends them. Last year I assembled a list of “2015 conferences I may want to attend”. I found it so useful that I did it again this year. Suggestions and corrections welcome!
It’s also possible to bypass the usual talk submission process by receiving a personal invitation to speak. I’ve been invited a few times. When this happens, it’s very flattering, and it drives home the continued need for me to participate in the usual process. I’ve had lots of talks rejected. If I hadn’t kept at it, gotten some acceptances, and made the most of them, the folks who’ve invited me to speak to their audiences wouldn’t have known I had anything to offer.
Moral of the story: keep submitting, keep presenting, keep practicing.
Write an abstract
I have not, by any stretch, mastered the art of writing a winning abstract. I do know what I like as an attendee. What draws me in? Among other things, I look for a story from personal experience. That helps me understand how being there might change my own story.
We discussed this on Agile for Humans 032.
Save a copy
If an abstract is accepted, I might want to submit it to more conferences. If an abstract is rejected, I might want to tweak it and submit it to more conferences. Either way, I don’t want to rely on being able to pull a copy out of a submission system. I do my writing in my personal wiki (an ikiwiki instance, naturally), then submit a copy.
Rejected? Try again from the top
Program committees and organizers don’t usually have time and energy to give personalized feedback. If my talk was rejected, it’s up to me to figure out what that might mean and what I might want to do about it. I might try to find someone who gives talks and get their personalized feedback. Or maybe it was one of the many perfectly good talks that get rejected all the time, and submitting verbatim to another conference is worth a shot.
I write a very short page linking to the conference, my session, and where to buy tickets (if they’re still available), and I tag the page talk-pending. That automatically adds it to the list of upcoming appearances on my speaker page, and also (via rss2email) turns it into an email message, which gets sent to my low-volume mailing list.
Sooner or later I’ll mention the talk on Twitter, etc., as well.
[Talk planning goes here]
I have no profound thoughts about how to put together a winning talk. Have experiences, figure out what’s interesting about them, extract the story arc.
I’m not, as yet, attempting to design fast-paced, visually arresting slides. I’ve been trying to keep it simple for myself instead. After several iterations, I’ve landed on a comfortable setup for writing and publishing decent web-based slides.
Last year, after migrating this site to ikiwiki, I was finally able to write new posts in Markdown. I wanted to be able to write slides in Markdown too. Remark.js does that. The easiest way to get started was to use it exactly as directed, then let ikiwiki’s rawhtml plugin preserve it for publishing.
The third time I published Remark.js slides, I noticed it was my third local copy of an old version of Remark.js. So I put it in a central place, adjusted the three references, and upgraded to the latest version — with git commits at each step, just in case I broke something. (I love having my site in git.)
This reduced duplication would certainly simplify my next slide-writing experience. To simplify it further, I wanted to extract the shared HTML and CSS. So I wrote a plugin for ikiwiki that provides the standard Remark.js template and styles, along with ikiwiki-idiomatic ways of overriding the template and styles.
Now I write
my_slides.remark just like I’d write
I locally preview the same way, too: commit, triggering an incremental
render. Quick and easy.
When the talk’s over, I:
- Squash unneeded intermediate commits
- Write a very short post linking to the abstract, slides, and any other related information
- Replace the very short publicity page with a redirect to the new post
This used to be a less streamlined process. Now I do it immediately after the talk.
At some point, it may become important to me to make fancier slides than Remark.js can produce. To do that, I’ll have to develop a new skill.
My employer — with offices in Columbus, Ann Arbor, and Des Moines and some consultants who don’t get to visit the offices very often — held its first ever internal conference, PillarCon. I chaired the “Delivery & Feedback” track, as part of which I held a breakout session on Cross-Platform Full-Stack Deployment (slides). I also gave a lightning talk on Web Architecture for Unix Lovers (slides).