Remote software work is increasingly common. At the beginning of my career, it was almost unheard of. But over the years it has grown steadily. I’ve been working from home for 10 years now, and when I gave a talk on the topic two years ago, fully half of the audience were working from home on a daily basis.
But there are still challenges.
For the past five years, I’ve been a part of a large software team that is heavily distributed: more than 60% of the LivingSocial engineering team works from home, spread across several time zones and a few countries. At its peak, the team was about 180 people, with well over 100 developers working from home or in small satellite offices or coworking spaces.
At the start—even after we had a substantial number of remote developers—the team managers worked at the office. That is a very common model. But eventually, as the team changed and grew, we found ourselves with managers working remotely, too. From 2013 through early 2016, my colleague Maria Gutierrez and I worked from our homes (me in Dallas, Maria in Edinburgh) as Engineering Directors, managing distributed teams ranging in size from 30 to 80. We made a lot of mistakes, but we also got a lot of things right, and we learned a lot from successes and failures alike. And at every step, we received valuable feedback from others at every level of our organization.
It seems like a good time to start sharing what we’ve learned. More companies are trying distributed teams. There are many reasons to do so. Here are just a few:
- A company might choose that direction, as LivingSocial did, to make it easier to recruit excellent developers.
- A company might want to provide more flexible working arrangements for its employees.
- One company might acquire or merge with other companies in different cities.
- Talented developers may wish to relocate for personal reasons, and the company might decide to “go distributed” rather than lose the valuable skills of loyal, dedicated employees.
- The company might move its headquarters to a different part of the city, with some team members asking to work from home rather than endure a longer commute.
Maria and I would like to share our experiences with those who might be starting down a similar path. In coming weeks, we’ll be blogging here about how to be effective in managing distributed software teams.
After a little over five years, I’m moving on from LivingSocial. What’s next for me? Well, I’m looking for the right position. At LivingSocial, we’ve spent five years learning how a distributed software development team can be really effective. I’d like to help another company build on that experience.
For the past three years I’ve been one of the leaders of our engineering team, overseeing a department ranging in size from 30 to 50 software developers and managers (part of a larger engineering team of about 150). The majority of those people—including me and other senior managers—have worked from home. It hasn’t all been smooth sailing, but we built a great team, learning valuable lessons about how a geographically distributed team can collaborate, manage work, recruit, train, mentor, maintain a healthy culture, and continually improve.
I’ve enjoyed being in the middle of that, working closely with our VP of Engineering and CTO, as well as the other department directors and the managers on my team. It’s been a wonderful opportunity to add a new dimension to my 25 years of experience as a developer and software architect.
In the software industry, remote work and distributed teams are becoming increasingly common. Many companies now have employees who work mostly from home or from other locations. And there are good reasons to pursue that as a strategy. But running a distributed team is different from running a colocated team, and it’s difficult to do it well. Most companies aren’t seeing as much effectiveness from their distributed teams as they (and the teams) would like.
If you are building a distributed team and would like a senior, experienced engineering leader with solid technical chops to help you succeed, please contact me:
- Email: glenn at this domain
- CV: https://www.linkedin.com/in/glennvanderburg
A little over a year ago, I gave a talk at Clojure/conj called Cló: The Algorithms of TEX in Clojure. It was very well received, and a surprising number of people were interested in the project (which at the time was only partly complete, unreleased, and in the middle of a substantial redesign).
A few people have been asking me about the status, so here it is: it is only partly compete, unreleased, and in the middle of a substantial redesign.
There are several reasons for that. The first one is that my job has kept me quite busy, with little time left over for a hobby project. But that wasn’t everything.
At the time I gave the talk, my mother was experiencing medical problems that would, over the next few months, bring her to her death on 20 April 2015 at the age of 95. In many ways it wasn’t a sad occasion: 95 is a ripe old age, and her quality of life had been poor for a long time, so the point of this isn’t to solicit condolences. But caring for her in those final months, the funeral, and then arranging a move for my dad a short time afterward took up most of my time.
But around the middle of 2015, I did start to get back to Cló again. And I realized something right away: before rebuilding Cló with my revised goals, I needed to become a better Clojure programmer. Cló was the largest Clojure program I had ever worked on, and the first one where I was in charge of the design. So as I returned to the project, I found myself trying to do several challenging things at once:
- Decipher the mind-mangling complexity of TEX’s code;
- Separate the optimizations from the essence of the algorithms;
- Recast those thoroughly procedural algorithms into a functional style;
- Correct the initial design mistakes from my first version of Cló; and
- Level-up as a Clojure programmer.
I can’t see a way around doing the first four simultaneously, but the last one can be done all by itself. I realized that it would be smart to get that one out of the way first, by practicing Clojure on a simpler project.
That project is snergly, a Clojure implementation of the algorithms in Jamis Buck’s wonderful book Mazes for Programmers. Toward the end of summer, before my job got too busy again, I built a command-line Clojure application that covered the first five chapters of the book. More recently, starting with a conference trip in early December and continuing through the Christmas holidays, I got that code working in ClojureScript to produce an animated, browser-based display. Along the way I’ve learned a lot (about both Clojure and ClojureScript, Om Next, Prismatic schema, and test.check).
I think I’m ready to take another run at Cló. The next time I have some spare time to hack on something, that’s the project I’ll be working on.
After a break of several years, I’ve decided to start blogging again.
I never decided to stop; I simply found myself not having much to say in a blogging context. But lately I’ve found myself wanting to write more. So I’ve converted my old rublog-based setup and I’m ready to go. Expect more updates soon.
Developers I encounter usually have a good grasp of coupling—not only what it means, but why it’s a problem. I can’t say the same thing about cohesion. One of the sharpest developers I know sometimes has problems with the concept, and once told me something like “that word doesn’t mean much to me.” I’ve come to believe that a big part of the problem is the word “cohesion” itself. “Coupling” is something everyone understands. “Cohesion,” on the other hand, is a word that is not often used in everyday language, and that lack of familiarity makes it a difficult word for people to hang a crucial concept on.
I’ve had some success teaching the concept of cohesion using an unusual approach that exploits the word’s etymology. I know that sounds unlikely, but bear with me. In my experience, it seems to register well with people.
Cohesion comes from the same root word that “adhesion” comes from. It’s a word about sticking. When something adheres to something else (when it’s adhesive, in other words) it’s a one-sided, external thing: something (like glue) is sticking one thing to another. Things that are cohesive, on the other hand, naturally stick to each other because they are of like kind, or because they fit so well together. Duct tape adheres to things because it’s sticky, not because it necessarily has anything in common with them. But two lumps of clay will cohere when you put them together, and matched, well-machined parts sometimes seem to cohere because the fit is so precise. Adhesion is one thing sticking to another; cohesion is a mutual relationship, with two things sticking together.
This is also why we refer to a sound line of reasoning, for example, as coherent. The thoughts fit, they go together, they relate to each other. This is exactly the characteristic of a class that makes it coherent: the pieces all seem to be related, they seem to belong together, and it would feel somewhat unnatural (it would result in tight coupling!) to pull them apart. Such a class exhibits cohesion. No glue is required, you don’t have to build extra code to make the pieces fit together; the pieces hang together naturally because they’re closely related. In contrast, sometimes a class will seem to have its fingers in way too many parts of your system. Such a class is adhesive, and that’s not what we’re looking for.
And whereas coherent means things fit well together, we use the word “adherent” to refer to a follower, and there’s a connotation that the follower isn’t necessarily wanted: a hanger-on.
There’s another common word that stems from the same root: “inherent”. Something that adheres sticks to something else, and two things that are coherent mutually stick to each other, but something that is inherent isn’t stuck to something so much as it’s embedded: it is an integral part of the other thing, tightly and inextricably bound. Although you don’t hear them very often, the two sister words “inhere” and “inhesion” are real words, as well.
So cohesion/cohesive/coherent occupy the middle territory between the sort of arbitrary, forced relationship of adhesion/adhesive/adherent and the integral, unbreakable relationship of inhesion/inhesive/inherent. That mental picture often helps me make wise decisions when I’m designing and refactoring. I want to build classes that are cohesive, not adhesive.