Working Remotely

A little over a year ago I took the plunge and joined a small startup working remotely as lead software engineer. I was nervous for a lot of reasons. This was my first lead position, my first job at a fully remote company. And being a startup, finances were not guaranteed. Could I handle it?

I did know a few things. The product was going to be interesting and fun to work on, while pushing me to grow and learn at the same time. There was a real demand for new features and infrastructure work. No time to ramp up. Development practices seemed forward facing, the tech stack and code modern. Not only fully distributed, the company was committed to fostering that culture both in tools and communication.

Five Lessons Learned In The First Year

It was July 2014. Finally fed up with the daily grind of commuting 3+ hours daily (thanks Seattle), I quit my job and started this adventure. Here are a few things I've learned along the way that have helped me adjust to this kind of work style. Hopefully these lessons can help you too.

Have A Schedule

Some distributed companies still keep core hours for various reasons. Usually it's to help facilitate communication among team members that are geographically distributed. Or, someone made an arbitrary decision to do so and it stuck. Company culture is weird like that.

Anyway, we don't keep core hours. Theoretically this lets each team member set a schedule that maximizes their own productivity. Practically, however, work and life have a way of leeching into each other, so that neither get the full attention they deserve. Focus is sacrificed, and eventually each side feels short-changed. Don't do this!

Set strict boundaries for when work takes precedence, and for when life takes precedence. Boundaries can be having a dedicated office space, with "work hours". Or telling your boss that you are unavailable after 6 PM. Next, set reasonable accommodations for exception cases (life: my kid has the flu; work: OMG production is burning). Then, communicate your plan. Tell your spouse/significant other, boss, coworkers, and dog.

I still wake up by alarm at 6 AM, every morning. Work is broken up into two main chunks, separated by a two to three hour lunch. Obviously this isn't a one size fits all answer, experimentation is encouraged.

Track Your Progress

It's easy to get lost in a waterfall of tasks, user stories, bug reports, etc. This is especially true in small companies. This is even more true in small, distributed companies.

Luckily I've never had the displeasure of having to justify my time on projects. However, it's still a good idea to track where time gets spent. We use Github, and we track progress in the form of issues and pull requests, organized around milestones. Milestones function as sprints, and every two weeks the current one closes and the next one opens. Right now we're on sprint 27.

A changelog gets updated with each release, highlighting PRs and issues closed since last release. Accountability is built in.

Face Time Is Valuable

If you want something done, grab someone and tell them to do it. You may need to tell them a few times.

If distributed, use video chat, and you may need to tell them a half dozen times.

Just don't bother with chat or email.

Embrace Asynchronous Communication

Chat and email do have a purpose. These are the tools that should only be used when an answer is needed within days if at all. Think company-wide emails, press releases, automated alerts, medium and low priority tasks, and idle banter. I'll refer to this kind of communication as low intensity communication.

Chat and email are great for low intensity communication. Know what they suck at? Accountability. Communication that is the opposite, high intensity. If something needs to get done, then chat and email are a great way to get ignored.

That being said, probably at least the majority of communication falls into the first category. Low intensity communication is important, on some scale, but also distracting in that it's usually not relevant to the task at hand. Contain it to communication channels that don't demand immediate attention.

Communicate, Communicate, Communicate

Like all of these points, good communication applies to any job, not just distributed ones. Aim to over communicate. Set expectations, send updates, ask questions, and report failures. Have daily video stand-ups, and weekly company meetings. Use email, chat, and text messages. Hold each other accountable. Document important decisions, and who made them. Then share that documentation. Good communication (or lack thereof) can literally mean success or failure for the entire organization.

Communication is like logging. Incident reports rarely cite too much of it.

Conclusion

This last year, with its ups and downs, has overall been very successful working remotely. The motivation dynamic can be much different, and I think it's crucial to be working on an interesting problem at a company that inspires. It's easy to lose motivation and put things off for later. Instead, keeping a schedule, communicating goals, and knowing the people who rely on you are great ways to stay on track and get stuff done.

There are incredible benefits to remote life. I became a dad in April, and having the flexibility to be with the little one during the day is very valuable. Mom gets a break and I get some bonding time. It's not enough time, but I'll take what I can get.

Thanks I hope you enjoyed reading!

Tags: remote


Make For Asset Management

tldr: the good stuff

Yes, that make.

$ man make

MAKE(1)

NAME
       make - GNU make utility to maintain groups of programs

Can this humble utility simplify a web developer's life managing a complex system of front end assets1?

In the past I used tools like Grunt, Gulp, Ant, and PHP's own Assetic to do this. Nothing felt right. Complex configurations, new scripts, new dependencies. There must be a better way.

Digression Warning

If anything is known about me, it is this: I'm lazy (proof). Don't make me do any extra work I don't have to do. Seriously. That previous sentence was only one word, that's how lazy I am. To me, laziness is an ideal. It's an ideal I can believe in, a rare gem awash in an ocean of ruthless pragmatism. But I digress.

Digression Averted, Make To The Rescue

Today, I want to talk about make. Make allows me to get work done faster so I can spend more time thinking about interesting problems, and less time building the plumbing for my web applications.

And, let's face it, plumbing carries shit. The less time I spend working on plumbing, the less time I have shit on my hands.

A Brief, Incomplete, Mostly Wrong History of Make

Make was originally introduced by Dr. Stuart Feldman of Bell Labs, in April 1976. Prior to widespread adoption of the utility, software was distributed with OS-specific "make" and "install" scripts. Make allowed multiple targets with commands to be written uniformly into one standardized build script. And this elegant solution is still one of the most widely distributed tools ever almost 40 years later.

Great. How Does This Relate To My Job?

The essence of make is to define repeatable transformations from a source to a target.

Ok. So what does that mean?

Transformations are shell commands, grouped into logical tasks by task name.

The source and target are filesystem objects. So what we have is a collection of shell commands, organized into logical groups of tasks, which define transformations in the filesystem.

Anatomy of a Makefile for the Web

By convention, a makefile's first target is a default catch-all, usually all:

all: clean build

More on this below.

Install

A web makefile is going to have different targets depending on things like libraries and the project structure. If dependencies are managed by Bower (and assuming bower is already configured and working), an install target like the one below works:

install:
    bower install

I usually have a few extra steps: convert a JS library from CommonJS to RequireJS, and create new distributable directories (note the buildDir macro2):

buildDir = /var/www/public

install:
    bower install \
    r.js -convert $(buildDir)/js/react-dropzone/ $(buildDir)/js/react-dropzone/ \
    mkdir -p $(buildDir)/js $(buildDir)/css \

Clean And Build

The build step compiles and releases a new set of CSS and javascript. For the example below, we're compiling LESS to CSS and JSX to vanilla JS. As the name implies, clean removes files generated during build.

assetsDir = /var/www/assets
buildDir = /var/www/public

build:
    cp -r $(assetsDir)/dist/* $(buildDir)/js \
    cp -r $(assetsDir)/dist/font-awesome/fonts $(buildDir)/fonts
    jsx --harmony --extension jsx --es6module $(assetsDir)/jsx $(buildDir)/js \
    lessc $(assetsDir)/less/master.less $(buildDir)/css/master.css

clean:
    rm $(buildDir)

Watching For Changes

Adding a --watch flag to the jsx command allows for automatic rebuild of JS resources when changed. Let's create a watch target for it.

watch:
    jsx --harmony --extension jsx --es6module --watch $(assetsDir)/jsx $(buildDir)/js

Putting It All Together

The makefile below contains two macros: assetsDir, buildDir, and four targets: install, build, watch, clean.

assetsDir = /var/www/assets
buildDir = /var/www/public

install:
    bower install \
    r.js -convert $(assetsDir)/dist/react-dropzone/ $(assetsDir)/dist/react-dropzone/ \
    mkdir $(buildDir)/js $(buildDir)/css

build:
    cp -r $(assetsDir)/dist/* $(buildDir)/js \
    cp -r $(assetsDir)/dist/font-awesome/fonts $(buildDir)/fonts \
    jsx --harmony --extension jsx --es6module $(assetsDir)/jsx $(buildDir)/js \
    lessc $(assetsDir)/less/master.less $(buildDir)/css/master.css

watch:
    jsx --harmony --extension jsx --es6module --watch $(assetsDir)/jsx $(buildDir)/js

clean:
    rm $(buildDir)

1. By assets, I'm referring to: javascript, preprocessed css, fonts, third party dependencies, and anything else that will eventually become accessible to the public. 2. Macros are variables local to the makefile.

Tags: make, frontend


Prototypal Inheritance In PHP

Generally, programming languages follow one of two types of inheritance patterns. These patterns describe how objects are defined, and how properties and methods are composed between them.

Classical Inheritance

Likely the most familiar pattern is classical inheritance, which is how PHP and many other languages are designed. Briefly, classical inheritance involves keywords like classes (abstract, final), objects, interfaces, and methods with special usage, like constructors and destructors. Classes extend other classes (single or multiple inheritance -- PHP implements single inheritance).

<?php

class vehicle {
    protected $engine = null;
    protected $milesTravelled = 0;
    protected $doorCount = 0;
}

class truck extends vehicle {
    // $engine, $milesTravelled, and $doorCount are inherited from vehicle
    protected $doorCount = 2;
    protected $hasTailHitch = true;
}

class motorcycle extends vehicle {
    // $engine, $milesTravelled, and $doorCount are inherited from vehicle
    protected $doorCount = 0;
}

$vehicle = new vehicle();
$truck = new truck();
$motorcycle = new motorcycle();

Prototypal Inheritance

The lesser known and used of the two patterns is prototypal, which is how Javascript handles inheritance, for example. Instead of classes and interfaces, there are only objects. Objects are dynamically assigned properties and methods, and new objects (children) inherit the properties and methods of the parent object, through the parent's prototype. The prototype is a reference to a set of properties and methods, and because it is a reference any changes are reflected across child objects sharing the same prototype.

<?php

$vehicle = new stdClass();
$vehicle->engine = null;
$vehicle->milesTravelled = 0;
$vehicle->doorCount = 0;

$truck = new $vehicle(); // doesn't work
$truck->doorCount = 2;
$truck->hasTailHitch = true;

$motorcycle = new $vehicle(); // doesn't work
$motorcycle->doorCount = 0;

Whoa, wait a minute. There isn't any structure to this code. This is a very dynamic and powerful concept that radically simplifies things. The only problem now is that the lines where we instantiate our children (truck and motorcycle) will not actually return the right results, since PHP is class-based and all (a runtime error will probably trigger).

Making Invocation Work

As a dynamic language, PHP is well suited to the protypal pattern, and has native support for assigning new properties (and methods as of 5.3+) to objects at run time, so most of the hard work has already been done for us. The only missing piece is native syntax for the invocation lines that create child objects. So what does it take to make those lines work? With a slight syntax tweak, turns out not much, actually:

<?php

public function __invoke() {
    return new self($this);
}

/**
 * In a hypothetical class, defining this magic method will allow the object to be invoked,
 * so instead of:
 *
 * $truck = new $vehicle();
 *
 * The syntax becomes:
 *
 * $truck = $vehicle();
 */

If we create a class and define its magic __invoke() method to return a new instance of itself, our object invocation syntax now works. In order to implement prototypal inheritance more completely, a little more work is involved, however, a well-formatted solution is still less than 100 LOC.