Conflict: Early And Often

Fear of conflict lengthens feedback loops.

We don’t bring up the little things because we want to be agreeable. But then when we finally decide we need to speak up, the feels have compounded.

Better is to embrace little conflicts. Get them out there, early and often. Don’t be afraid of them. You’ll get better at navigating complex situations with particular people and in general. With particular people, you’ll start to understand where you disagree and where you can and can’t find consensus. And in general, you’ll start to understand how to get to that place, with different kinds of people.

Early And Often

We developers like to say you should build early and often. You should commit early and often. Update your code from master early and often. Test early and often. Integrate, early and often. Get your work in front of your actual users, you guessed it, early and often.

Long feedback loops mean small conflicts add up. But the effort required to deal with them doesn’t grow linearly. It’s not the sum of all your little conflicts. It’s worse. You have to juggle. Things compound.

Short feedback loops mean you’ll see problems sooner. You’ll see more problems more often, but you’ll see them when they’re small. They’ll be more approachable. You can fix them in minutes, rather than hours or days. You’ll start expecting them, even looking for them.

Small and frequent rather than large and infrequent. Early and often.

First Things First

If the first thing you do when you sit down to work is open up your email, you might spend your whole day reacting to what’s in your inbox.

Your energy gets depleted over the course of the day. If you let it get drained by the urgent, you might never get around to the important.

Figure out the most important thing to do today. Do it before you do anything else. Do it before you open your email or check your feeds.

Destructuring Assignment In JavaScript

“Destructuring assignment” isn’t the friendliest name. I think that’s because it’s an unfamiliar concept. Look at just these few examples and I think you’ll be able to get your head around it.

Consider a JS array or an object:

let myArray = [
  'Maya',
  'Ray'
];

let myObject = {
  firstName: 'Tony',
  lastName: 'Baloney'
};

Each of these is more complex than a single value, like 5 or 'foo'. Each has a structure: The array is an ordered list of stuff. The object is basically a collection of key/value pairs.

When you do a destructuring assignment, what you’re doing is reaching into the structure of an array or an object to get at something inside it, and assigning that something to a variable outside.

With an array, it looks like this:

let myArray = [
  'Maya',
  'Ray'
];

let [one, two] = myArray;

console.log(one); // prints 'Maya'
console.log(two); // prints 'Ray'

With an object:

let myObject = {
  firstName: 'Tony',
  lastName: 'Baloney'
};

let { firstName: first, lastName: last } = myObject;

console.log(first); // prints 'Tony'
console.log(last); // prints 'Baloney'

In both cases, you provide some structure on the left side of the assignment statement. This information is needed for JS to know how to map stuff from inside the array or object onto your new variables.

There are lots of small notes about the ins and outs of destructuring assignment. I’m tempted to add them, but my goal here is to introduce the concept and basic syntax, not to provide documentation.

Okay, one small note: With an array destructuring assignment, you can use the spread operator!

let beatles = [
  'John',
  'Paul',
  'George',
  'Ringo'
];

let [first, second, ...rest] = beatles;

console.log(first); // prints 'John'
console.log(second); // prints 'Paul'
console.log(rest); // prints 'George,Ringo'

Apologies to George and Ringo.

JavaScript’s Spread Operator

The spread operator is handy when you want to call a function with some arguments and you have those arguments in the form of an array. It lets you pass the array, and spreads the contents of the array across the arguments expected by your function.

It’s a situation like this:

function getTotal(a, b, c) {
    return a + b + c;
}

let params = [1, 2, 3];

I can’t call getTotal(params) here. getTotal wants individual parameters, not a single array.

I could do the spread manually, in code:

getTotal(params[0], params[1], params[2]);

Kind of unpleasant, verbose. And it doesn’t really work if I want to support situations where params can have a variable length.

I could use Function.prototype.apply for that:

getTotal.apply(null, params).

Reasonable, but still not ideal. Before ECMAScript 2015, this is what I’d have suggested you do.

The spread operator is a nicer, cleaner way:

getTotal(...params);

Looks like the syntax for rest parameters, right? I’m sure that’s no coincidence. They represent similar concepts, just in different directions. In a function definition, the dot-dot-dot says “turn this list of args into an array”. In an invocation, the dot-dot-dot says “turn this array into a list of args”.

Try Shit

If you only ever do things in the context of a goal, you’re missing out. Goals are good, but there’s plenty of opportunity out there that you don’t know about. Finding it means discovery, and discovery means trying shit. Without an end in mind.

There are unknown unknowns. It’s possible to not know what you’re missing.

One Of These Days

You don’t need to add items like “play video games” to your to-do list. You do them. Because you want to do them.

But there are those other things. Things that have been on your to-do list for years that you just haven’t gotten around to yet. You never make time for them. But one of these days, you will. You’ll learn to play that dusty guitar in the basement. You’ll write your screenplay, your novel, your cookbook. You’ll get your Master’s degree. You’ll train for a marathon. You’ll remodel the kitchen.

Bullshit.

If you keep telling yourself you want to do something but never actually do it, at some point you have to stop, look at your actual behavior, and ask yourself whether you really want that thing.

Maybe you want to want it. Maybe you really do want it but don’t have any idea how to get there. (Make a plan, then. Start asking questions, like “what’s holding me back?”) Maybe you’re afraid of failure. Or afraid of success.

Whatever the case, the psychic cost of long-term inaction is not small. There’s a tiny feeling of failure every time you think about it. That adds up.

Consider letting go. Admit it: This distant thing is not a real goal. You haven’t made progress toward it, you’ve taken no action, and you have no intention of taking action any time soon.

How would that feel?

Blind Emulation

Have you heard the term “cargo cult”? I learned it from a Richard Feynman essay:

In the South Seas there is a cargo cult of people. During the war they saw airplanes land with lots of good materials, and they want the same thing to happen now. So they’ve arranged to imitate things like runways, to put fires along the sides of the runways, to make a wooden hut for a man to sit in, with two wooden pieces on his head like headphones and bars of bamboo sticking out like antennas—he’s the controller—and they wait for the airplanes to land. They’re doing everything right. The form is perfect. It looks exactly the way it looked before. But it doesn’t work. No airplanes land. So I call these things cargo cult science, because they follow all the apparent precepts and forms of scientific investigation, but they’re missing something essential, because the planes don’t land.

When you get the what but not the why of your solution, you’re bound for failure.

Developers see this. In our naive early days, we copy and paste code into our project without reading it. Maybe it’s code from the internet. Maybe it’s from a different project in the company. We copy it without bothering to really understand what it does. Maybe it works for a while, but then we find a bug, or requirements change, and we’re hosed: Suddenly, we have to do the hard work of learning what this code even does before we can even consider how to change it. Yuck.

We get cargo culty with our code. We do it with patterns. We do it with tools (move to git but use it the same way we used Subversion). We do it with process (pretty much every Scrum implementation I’ve ever seen). This pattern exists at every level.

Copying a successful behavior without understanding it can work, but it’s almost never a good idea. If you don’t understand why it worked, you can’t be sure it’ll work in your situation. Your situation is almost certainly different.

Even if it does work for your situation, it can’t help but be a fragile solution: If your situation changes, even slightly, this behavior may become ineffective. You won’t understand why. You won’t be equipped to adjust it.

There’s no getting around the need for good, old-fashioned thinking.

Prescriptive/Descriptive

Prescriptive: This is how it should be. In theory. Sentences may not end with prepositions. That word doesn’t mean this. This word isn’t pronounced like that or spelled like that. The work is to be done in such and such a fashion.

Descriptive: This is how it is. In practice. Sentences end with prepositions sometimes. Words’ meanings, pronunciations, and spellings are messy. The job gets done how it gets done.

When you spend a lot of time and energy mastering a complex technical skill, you develop a strong desire to be prescriptive. “I’ve learned how this works. It was hard. You’re doing it wrong.”

It makes sense: You’ve made an investment in learning the rules. Now you want to show people how to follow them.

The rules are there for a reason. They’re usually the sum of many hard-won lessons. We’ve found that things work better when we follow them.

But the rules do change. They change when people break them. People discover ways things can work a little better. One gal tries something just a little different, the next guy notices and follows suit, and so on and so on. One day we wake up and notice that the rules aren’t what they used to be.

It’s great to know the rules, but hold on loosely.

Rest Parameters In JavaScript

Functions that can take a variable number of arguments are called “variadic functions”.

Sounds fancy, right? I’m guessing even if you haven’t heard the term, you’re familiar with the concept. Functions like this are not uncommon.

Let’s look at a simple variadic function in JavaScript:

function sum() {
  let total = 0;

  for (let i = 0; i < arguments.length; i++) {
    total += arguments[i];
  }

  return total;
}

sum(1); // returns 1
sum(1, 2, 3); // returns 6

Notice how sum has no parameters in its function header. Instead, it uses a special object called arguments. arguments acts kind of like an array, containing all the arguments passed to the function.

If you call sum with a single argument, arguments will have only that one. If you pass sum a dozen arguments, they’ll all show up in arguments.

Note: arguments is array-like, but it is not an actual array. You have to jump through some hoops if you want to do certain arrayish things with arguments. This can be annoying.

ECMAScript 2015 introduces some new syntax that can make variadic functions a little cleaner.

function sum(...numbers) {
  let total = 0;

  for (let i = 0; i < numbers.length; i++) {
    total += numbers[i];
  }

  return total;
}

No more arguments! We’ve added this new ...numbers parameter. This is a rest parameter. It says “I’m an (actual) array! Fill me up with all the arguments you were called with, from this point on in the list.”

In our new-and-improved sum, the rest parameter ...numbers captures all the arguments, because it’s first in the list. But a rest parameter could come at the end of a longer list of parameters, like so:

function foo(bar, baz, herp, derp, ...etc) {
  // ...
}

You can call foo with any number of arguments. The first four will be bound to bar, baz, herp and derp, and any additional ones after those four will fill up etc.

If you try to define a function with a parameter after a rest parameter, an error will occur.

For example:

function foo(...bar, baz) {}

In Chrome, this line throws an error: Rest parameter must be last formal parameter. This makes sense, because ...bar will capture all arguments in its array. No argument values could ever get into baz.