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.
Michael Feathers just put up a blog post on a topic that’s near and dear to my heart: Ending the Era of Patronizing Language Design. I can’t resist chiming in. (This post might be more interesting if I disagreed with him on some point, but I just don’t. I just want to emphasize some of Michael’s points and offer some supporting anecdotes.)
Michael writes, “For years, in the software industry, we’ve made the assumption that some language features are just too powerful for the typical developer—too prone to misuse.” I’ve heard that argument many, many times, from people I strongly respect. And for a long time I believed it. For several years after I became enthusiastic about Ruby, I worked in places where most of the developers were typical, average programmers, and I refrained from really pushing Ruby in those environments because I thought Ruby was too powerful for them.
Then, a few years ago, I spent some time in a role where I was doing architectural reviews of IT projects (mostly Java projects). And one day I came to a shocking realization: there’s no way those projects could have been screwed up any worse if they had been written in Ruby.
What was alarming and depressing about those Java projects I was reviewing was not that they were poorly designed. I expected that; design is, after all, difficult. No, the surprising thing was that somehow, against all odds, the developers had managed to wrestle these monstrous designs over the finish line. The sheer dogged determination it took to do so was impressive and horrifying. I would have given up in despair long before.
The experience taught me a valuable lesson:
Weak developers will move heaven and earth to do the wrong thing. You can’t limit the damage they do by locking up the sharp tools. They’ll just swing the blunt tools harder.
I’ve been working full-time in Ruby now for almost four years. Everything I’ve seen while working on Ruby projects confirms what I realized back then, and it matches what Michael wrote about the ethic of responsibility that a powerful language like Ruby fosters. Ruby isn’t a panacea. The weak developers will wreak havoc in Ruby projects as well. But I think Ruby also makes it more difficult to hide from those mistakes without learning something from them. Yes, many Ruby projects have design weaknesses, but the usual standard is better than what I’ve seen in other languages, not worse.
If you want your team to produce great work and take responsibility for their decisions, give them powerful tools.