Nicholas C. Zakas's Blog, page 6
April 14, 2015
Consensus-Driven Development
If you grew up in a democratic country, chances are you were taught at a young age about the importance of democracy and people’s right to vote. Children growing up in the United States, in particular, are inundated with the message that democracy is the best form of government and voting is the best way to determine the correct course of action. We are then often shell-shocked when we get out of school and discover that, in may cases, our voices don’t matter. Democracy and voting, while important for running the country, are often inefficient and ineffective in our every day lives.
The challenges of software
Software engineering is interesting due to the plurality of opinions around nearly everything: which programming language to use, how to write your code using that language, the patterns to apply in your code, how to name things, feature language features are good or bad, and the list goes on. What’s more, software engineers tend to be quite loud about their preferences, sometimes at the expense of decorum, even in situations where the outcome has already been determined or doesn’t matter.
And yet, somehow we need to move the conversation forward and get our work done. Everyone’s first reaction? We should vote on it, and the majority rules. However, making group decisions based on a vote is rarely the right way to go. As a technical leader, you need to find a way to move forward.
The problem with voting
There is a hierarchy in any group of people. At one end are the people of power and influence and at the other end are those without. This spectrum exists even in today’s “flat org structures,” meaning that there is an imbalance within any group as to who is able to affect the most change. The most influential and the most willing to speak up can sway a group in one direction or another as the shy or less self-assured people feel content to follow their lead.
The long-term effects of such a setup are, I believe, detrimental to the health and well-being of the team as a whole. Voting can help determine the winner but cannot ensure that everyone is on the same page. Some of the negative effects I’ve seen in these situations are:
Holding grudges – there are few things more demoralizing than having your idea voted down. If it happens frequently, it tends to lead to hard feelings and people being less willing to share their ideas.
Centralized power – the people whose ideas get voted up most frequently start to have an overwhelming effect on the group as a whole. Those people can easily sway the group, effectively changing it from a democracy into an authoritarian system (which leads to resentment).
Split decisions – when a vote ends up tied or is mostly split down the middle (6-5, 2-3), it means the group really hasn’t made a decision.
When these situations start to happen, the code and people’s behavior will reflect the growing angst on the team. People will explicitly not do what was voted on as a form of rebellion against what they perceive to be an unfair system; people will leave because they feel like they don’t have a voice; people will quietly grow more resentful and their work will suffer.
So how can a group make decisions in an effective way where everyone buys in?
Driving consensus
Wikipedia defines[1] consensus as:
Consensus decision-making is a group decision-making process that seeks the consent of all participants. Consensus may be defined professionally as an acceptable resolution, one that can be supported, even if not the “favourite” of each individual.
This is why consensus is a much better tool for making decisions on a team: it requires the input of each individual and an explicit agreement to abide by the decision even if you don’t personally agree. This is a powerful difference from the majority rules approach of democratic voting.
Consensus-building, however, takes a lot more work than simple majority-rules voting. It requires significantly more discussion because you must find a resolution that everyone will agree to follow. In order to do that and avoid going back to vote, there are some things I do to move the process forward:
Agree on how to agree – the first step is set expectations for the group and explain that you’re looking to gain consensus, and that means having everyone bought into the decision. It’s also helpful to frame the discussion based on the impact of the decision. For low-impact decisions, you should set a time limit by which a decision will be made (it doesn’t make sense to debate for days a decision whose implementation has no significant impact); for high-impact decisions, lay out the important points to be discussed.
Take the temperature of the room – before getting started, ask for people’s thoughts on the topic at hand in a free-form way. Sometimes you’ll find there is already general agreement and therefore you can move to a final decision fairly quickly. Don’t extend the conversation any further than necessary. The other times, you can get a sense of how far apart various sides are on a topic. Either way, you get a good picture of how the team is feeling about the topic.
Encourage competing views – when someone makes a strong point, ask if anyone would like to counter the claim. The only way you can drive consensus is to make sure all the information is presented. Questions like, “does anyone feel differently?” or, “does anyone disagree with that?” help to everyone to focus in on the issue and think more deeply about their perspective.
It’s important to keep control over the conversation by making sure the tone stays positive and constructive, and that the group doesn’t start recycling topics. Equally important is ensuring that everyone who wants to speak is heard, and that missing details are added into the conversation whenever possible. Some phrases that help to guide the conversation:
Does anyone have experience with that? Has anyone experienced the opposite?
Has anyone else found that to be true?
How do people feel about that suggestion?
Finding agreement
Once you feel that there is enough information to make a decision, it’s time to get everyone in the room to commit. There are several ways to determine the final decision. I’ve used all of these at some point, depending on the situation:
General agreement – if it seems like there’s already consensus, you can stop and ask if there’s any strong objections to moving forward with the decision. If not, then you’re done.
Defer to the champion – sometimes a topic is very important to one or two people, and not at all important to everyone else. Those people will give impassioned speeches about their point while the rest of the group doesn’t seem to have an opinion. In this case, I tend to suggest that the group follow the lead of those who are most passionate about the topic. This works on a number of levels: people know that their voice will be heard when they are passionate about something and the group learns that debating just for the sake of debating isn’t useful. If someone is willing to champion a position, and there is no strong opposition, then it makes sense to drive towards the champion’s position.
Champions debate – sometimes there are people who are passionate about opposite positions, so you have two champions rather than just one. In this case, it can be helpful to focus the conversation around these champions and see if they can determine between them if one is truly more passionate than the other. I’ve found that you can get to a point where one of them will defer and realize they don’t care as much about the outcome as they previously thought. If that happens, then you’re back to a one-champion model. If it doesn’t, then it’s time to move on to another strategy.
Taking turns – sometimes the best way to drive consensus is through the childhood practice of taking turns. This approach is most useful when there are opposing champions who can’t seem to work out their differences. If one of them has more recently had a group decide in their favor, then it helps to suggest that it may be the other person’s turn to have their opinion be the consensus. The innate sense of fairness that most people have can sometimes short circuit an otherwise contentious battle.
Voting – yes, sometimes consensus can be gained through voting. However, the difference between this and majority-rules is that voting is used simply to determine how close to consensus the group is. If it’s still a split, it means that there’s information in the discussion; if there are a handful of outliers, you can use of the previous approaches to see if they will abide by the general agreement; if it is unanimous, then consensus has been reached. I tend to use voting only as a last resort if the other approaches have failed.
The most important aspect of driving consensus is that everyone must be bought into the decision once made. That means people must be comfortable with the idea of disagreeing while supporting the decision. To gain that closure, it’s important that any dissenters are asked specifically, “I know you disagree with the decision, but is it something you can live with and support?” You haven’t reached consensus until each dissenter answers that question with a, “yes.”
Conclusion
Consensus-driven development, the use of consensus on software development teams, is a health way to solve disputes and make decisions as a group. I’ve found that using this approach leads to better morale and stricter adherence to decisions. It doesn’t matter if the topic is code conventions, third-party libraries, or which tools to use, making these decisions by consensus has a positive effect on the process.
Keep in mind that consensus is best used in situations where the available options are similar enough that there’s no clear best choice (or no clear worst choice). It’s also important to remember that not all decisions are suitable to be made in groups. In all companies, there are some decisions that are individual and some that are group; trying to recast an individual decision as a group decision tends not to work, and consensus isn’t appropriate in such situations.
In situations where group decisions are appropriate, consensus is a great tool to use. It does require a strong leader who can manage the process and keep the level of discourse up (consensus can’t be built without someone guiding the conversation), so make sure that someone is appointed to do so before giving it a try.
References
Consensus decision making (Wikipedia)





April 13, 2015
Consensus-Driven Development
If you grew up in a democratic country, chances are you were taught at a young age about the importance of democracy and people’s right to vote. Children growing up in the United States, in particular, are inundated with the message that democracy is the best form of government and voting is the best way to determine the correct course of action. We are then often shell-shocked when we get out of school and discover that, in may cases, our voices don’t matter. Democracy and voting, while important for running the country, are often inefficient and ineffective in our every day lives.
The challenges of software
Software engineering is interesting due to the plurality of opinions around nearly everything: which programming language to use, how to write your code using that language, the patterns to apply in your code, how to name things, feature language features are good or bad, and the list goes on. What’s more, software engineers tend to be quite loud about their preferences, sometimes at the expense of decorum, even in situations where the outcome has already been determined or doesn’t matter.
And yet, somehow we need to move the conversation forward and get our work done. Everyone’s first reaction? We should vote on it, and the majority rules. However, making group decisions based on a vote is rarely the right way to go. As a technical leader, you need to find a way to move forward.
The problem with voting
There is a hierarchy in any group of people. At one end are the people of power and influence and at the other end are those without. This spectrum exists even in today’s “flat org structures,” meaning that there is an imbalance within any group as to who is able to affect the most change. The most influential and the most willing to speak up can sway a group in one direction or another as the shy or less self-assured people feel content to follow their lead.
The long-term effects of such a setup are, I believe, detrimental to the health and well-being of the team as a whole. Voting can help determine the winner but cannot ensure that everyone is on the same page. Some of the negative effects I’ve seen in these situations are:
Holding grudges – there are few things more demoralizing than having your idea voted down. If it happens frequently, it tends to lead to hard feelings and people being less willing to share their ideas.
Centralized power – the people whose ideas get voted up most frequently start to have an overwhelming effect on the group as a whole. Those people can easily sway the group, effectively changing it from a democracy into an authoritarian system (which leads to resentment).
Split decisions – when a vote ends up tied or is mostly split down the middle (6-5, 2-3), it means the group really hasn’t made a decision.
When these situations start to happen, the code and people’s behavior will reflect the growing angst on the team. People will explicitly not do what was voted on as a form of rebellion against what they perceive to be an unfair system; people will leave because they feel like they don’t have a voice; people will quietly grow more resentful and their work will suffer.
So how can a group make decisions in an effective way where everyone buys in?
Driving consensus
Wikipedia defines1 consensus as:
Consensus decision-making is a group decision-making process that seeks the consent of all participants. Consensus may be defined professionally as an acceptable resolution, one that can be supported, even if not the “favourite” of each individual.
This is why consensus is a much better tool for making decisions on a team: it requires the input of each individual and an explicit agreement to abide by the decision even if you don’t personally agree. This is a powerful difference from the majority rules approach of democratic voting.
Consensus-building, however, takes a lot more work than simple majority-rules voting. It requires significantly more discussion because you must find a resolution that everyone will agree to follow. In order to do that and avoid going back to vote, there are some things I do to move the process forward:
Agree on how to agree – the first step is set expectations for the group and explain that you’re looking to gain consensus, and that means having everyone bought into the decision. It’s also helpful to frame the discussion based on the impact of the decision. For low-impact decisions, you should set a time limit by which a decision will be made (it doesn’t make sense to debate for days a decision whose implementation has no significant impact); for high-impact decisions, lay out the important points to be discussed.
Take the temperature of the room** – before getting started, ask for people’s thoughts on the topic at hand in a free-form way. Sometimes you’ll find there is already general agreement and therefore you can move to a final decision fairly quickly. Don’t extend the conversation any further than necessary. The other times, you can get a sense of how **far apart various sides are on a topic. Either way, you get a good picture of how the team is feeling about the topic.
Encourage competing views – when someone makes a strong point, ask if anyone would like to counter the claim. The only way you can drive consensus is to make sure all the information is presented. Questions like, “does anyone feel differently?” or, “does anyone disagree with that?” help to everyone to focus in on the issue and think more deeply about their perspective.
It’s important to keep control over the conversation by making sure the tone stays positive and constructive, and that the group doesn’t start recycling topics. Equally important is ensuring that everyone who wants to speak is heard, and that missing details are added into the conversation whenever possible. Some phrases that help to guide the conversation:
Does anyone have experience with that? Has anyone experienced the opposite?
Has anyone else found that to be true?
How do people feel about that suggestion?
Finding agreement
Once you feel that there is enough information to make a decision, it’s time to get everyone in the room to commit. There are several ways to determine the final decision. I’ve used all of these at some point, depending on the situation:
General agreement – if it seems like there’s already consensus, you can stop and ask if there’s any strong objections to moving forward with the decision. If not, then you’re done.
Defer to the champion – sometimes a topic is very important to one or two people, and not at all important to everyone else. Those people will give impassioned speeches about their point while the rest of the group doesn’t seem to have an opinion. In this case, I tend to suggest that the group follow the lead of those who are most passionate about the topic. This works on a number of levels: people know that their voice will be heard when they are passionate about something and the group learns that debating just for the sake of debating isn’t useful. If someone is willing to champion a position, and there is no strong opposition, then it makes sense to drive towards the champion’s position.
Champions debate – sometimes there are people who are passionate about opposite positions, so you have two champions rather than just one. In this case, it can be helpful to focus the conversation around these champions and see if they can determine between them if one is truly more passionate than the other. I’ve found that you can get to a point where one of them will defer and realize they don’t care as much about the outcome as they previously thought. If that happens, then you’re back to a one-champion model. If it doesn’t, then it’s time to move on to another strategy.
Taking turns – sometimes the best way to drive consensus is through the childhood practice of taking turns. This approach is most useful when there are opposing champions who can’t seem to work out their differences. If one of them has more recently had a group decide in their favor, then it helps to suggest that it may be the other person’s turn to have their opinion be the consensus. The innate sense of fairness that most people have can sometimes short circuit an otherwise contentious battle.
Voting – yes, sometimes consensus can be gained through voting. However, the difference between this and majority-rules is that voting is used simply to determine how close to consensus the group is. If it’s still a split, it means that there’s information in the discussion; if there are a handful of outliers, you can use of the previous approaches to see if they will abide by the general agreement; if it is unanimous, then consensus has been reached. I tend to use voting only as a last resort if the other approaches have failed.
The most important aspect of driving consensus is that everyone must be bought into the decision once made. That means people must be comfortable with the idea of disagreeing while supporting the decision. To gain that closure, it’s important that any dissenters are asked specifically, “I know you disagree with the decision, but is it something you can live with and support?” You haven’t reached consensus until each dissenter answers that question with a, “yes.”
Conclusion
Consensus-driven development, the use of consensus on software development teams, is a health way to solve disputes and make decisions as a group. I’ve found that using this approach leads to better morale and stricter adherence to decisions. It doesn’t matter if the topic is code conventions, third-party libraries, or which tools to use, making these decisions by consensus has a positive effect on the process.
Keep in mind that consensus is best used in situations where the available options are similar enough that there’s no clear best choice (or no clear worst choice). It’s also important to remember that not all decisions are suitable to be made in groups. In all companies, there are some decisions that are individual and some that are group; trying to recast an individual decision as a group decision tends not to work, and consensus isn’t appropriate in such situations.
In situations where group decisions are appropriate, consensus is a great tool to use. It does require a strong leader who can manage the process and keep the level of discourse up (consensus can’t be built without someone guiding the conversation), so make sure that someone is appointed to do so before giving it a try.
References
Consensus decision making (Wikipedia)





July 15, 2014
Generalists and specialists: thoughts on hiring
In my career, I’ve worked at companies of all shapes and sizes. From the very tiny five-person failed startup WellFurnished to the 13,000-strong Yahoo to the around 1,000-person Box (my current employer). During that time, I’ve been a part of many different engineering organizations that have had very different philosophies about hiring engineers. I’ve interviewed and hired a lot of people in my time and have a pretty good track record at identifying good future colleagues.
Throughout my different jobs I’ve found that the primary distinguishing factor in hiring practices has come down to a single point: whether the company believes in hiring generalists or specialists. While I don’t believe there is one true way to build an engineering organization, I do believe that the size of the company and its stage of existence necessarily influences the approach.
Generalists and young companies
A generalist is someone who, by definition, has no particular specialty. They probably graduated with a computer science degree and is good doing a lot of what I’d describe as server-side activities: databases, infrastructure, builds, deploys, data manipulation and processing, and so on. Generalists don’t mind jumping from C++ to Python to Java in the course of their work, as many languages are similar enough that there aren’t huge barriers to making the transition. They are real workhorses, able to take on whatever is thrown at them.
Generalists tend to do a good but perhaps not great job on a lot of things and tend to struggle on things that require a different mode of thinking. For instance, many generalists struggle with taking on front-end or mobile work. The paradigm is so different that there’s not enough common ground to make these work well, and so those parts of the product tend to suffer a bit in the presence of generalists.
The early stages of a company are the ultimate expression of constrained resources. Even if you successfully raise money, it likely isn’t enough to hire all of the people you actually need. As such, anyone who joins the company is going to be expected to wear many hats and do many things. I signed on to WellFurnished to do the front-end and ended up setting up our infrastructure, source control, and build and deploy system. At that point, when looking for help, I mostly looked for generalists who could hop in and help in any number of places.
Young companies don’t have the luxury of hiring people who can only do one thing or a small subset of things. There’s too much work to do and not enough people to do it. Generalists are the way that the business gets off the ground and makes something works. Everyone needs to be working on something all of the time or you’re wasting a very limited resource: money.
At this stage, there’s also a certain pragmatism to the technical approach. The entire system is relatively small and so it’s possible (and necessary) for each engineer to understand each part of the system. Being able to keep the entire system in your head is key at this point, because everyone needs to be able to do just about everything.
Introducing specialists
Specialists, on the other hand, are people who excel at a particular type of thing. They have made room in their brains for deep knowledge of a particular area and, in doing so, have necessarily forgotten (intentionally or not) some of the things that generalists know top-of-mind. What specialists bring to the table is a level of excellence in something specific. They have devoted their career to focusing narrowly on something and, as a result, are much better at that thing than a generalist could ever be.
Early on at a company, generalists create a lot of “good enough” solutions. That’s not to say this is a bad strategy, it’s just a fact of how companies grow. The “good enough” solutions are, as the name suggestions, good enough to get the company to its next stage growth. Sometimes it’s good enough to get the company through two or three stages of growth. But eventually, “good enough” won’t be good enough anymore, and that’s when you need to start hiring specialists.
Not good enough comes in many forms. The most obvious is in the front-end: every company I’ve been at that focused on hiring generalists has had a terrible time getting any sort of quality front-end built. Designers get frustrated because the engineers can’t figure out how to make what they designed, and product managers are frustrated because the front-end is a key differentiator to end users. At that point, someone starts asking if it’s time to hire someone who “really knows this stuff.”
This is often a controversial topic for smaller companies that are growing into larger ones. The main arguments against hiring specialists tend to be:
We don’t know how. The interview process is tailored for generalists. That lends itself to interview processes filled with general-purpose computer science knowledge in an effort to determine if the candidate is “smart.” There’s algorithms and data structures and discussions of complexity – all designed not to test individual skills but rather to test concepts and ideas that should be transferable to any programming language. A generalist should, after all, be able to just pick up another language so long as the concepts are solid. Once a company is used to labeling candidates as “smart” or not based on this type of interview process, it’s very hard to make a switch. In fact, “smart” is a dynamic term that doesn’t apply equally to everyone. But how can you properly vet a specialist if that specialization isn’t represented at the company?
It creates resource allocation problems. One of the theories behind hiring generalists is that you’ll have a small army of roughly-equivalent resources to assign to projects. If everyone is capable of doing everything, you have ultimate flexibility in resourcing projects. You don’t have to wait for Jim to come free or for Mary to finish up her last project. If an engineer becomes available, you assign them to the next thing. Specialists, by definition, are limited in what you can assign them to work on. That fundamentally shifts how resource allocation works within the engineering organization: all of a sudden there’s one person who can only do a subset of the work. The whole system is thrown into an unstable state because of this one discrepancy.
If you’re a specialist reading this list, you’re probably thinking, “those are bullshit reasons.” If you’re a generalist reading this list, you’re probably thinking, “well duh, obviously.” So I’ll split the difference and say that these concerns are real and valid, however, they are far from unsolvable. Many companies have tread this path and have come out successful. The trouble is always getting that first specialist in the door to prove the system can work.
Do we really need a specialist?
Whether or not you really need a specialist tends to come down to how dire your situation is and generally falls into one of two categories:
Stuff is really broken. Unfortunately, this is the more common scenario. After months or years of hacking away at something, things are such a mess that “good enough” is now considered “horrible”. You need someone who already knows how to fix the problem.
Moving into a new area. A lot of companies will want to hire specialists when they’re moving into a new area of business and need to execute quickly. For instance, introducing a mobile application when they’ve only done web applications, or vice versa. This is a nice opportunity for the specialist because they get a blank slate to show they know their stuff. Unfortunately, these opportunities don’t come along very often.
The first situation, things becoming a big mess, is pretty much how I’ve made my career both as an employee and as a consultant. The second situation was most recently experienced by mobile developers as all companies rushed to create mobile apps.
The question of whether you real need a specialist or not can also be answered by looking at the current resource allocation. If you see the same part of the system constantly needing attention (i.e., the web front-end or the mobile app), then chances are the generalists are no longer cutting it.
Hiring a specialist
Eventually, every successful company will hire their first specialist – it’s a virtual certainty. The first step is to figure out how to hire that specialist. You need to accept that your current interview process probably doesn’t apply. On top of that, specialists tend to get frustrated with questions that have nothing to do with what they’re good at. So how do you interview for a specialist when your company doesn’t have that specialization?
While you’re company doesn’t have any specialization, it does have people who have worked on the specific problems you want the specialist to work on. Those are the people who should be conducting the interview. The simplest way to go forward is to discuss the current problems you’re having and ask candidates how they would go about solving them. This isn’t about getting free work from random people, as it’s likely impossible to solve these problems completely during the course of an interview. Rather, it’s about getting the candidates to teach you about the context of the problem and understanding their thought process. Good specialists will be able to tell you the area of the problem and how they would go about investigating and potentially fixing it.
This ability to clearly communicate to people outside of their specialization is really important for a first specialist hire since that’s what they’ll be doing all the time. Because no one else will know exactly what they’re doing, you need to be able to trust the specialist to communicate clearly and in a way that everyone can understand. In the end, understanding how the candidate will address the problem and agreeing that it makes sense is the best way to make this first hire.
The second part of the problem, resource allocation, tends to fix itself. Many generalist-minded engineering VPs fear that the specialist will be left without enough to do such that they become a money sink. In practice, there’s usually enough work for the specialist to focus on in the beginning that this isn’t a big issue. Either cleaning up a mess or creating a completely new product means that the specialist will have plenty to keep them busy for a decent amount of time. After that point, it’s typically the case that once an engineering team has developed a competence in something, they want to add more to it. The web application starts needing new end-user features and the mobile apps needs some new functionality. Oftentimes, you’ll find that within a year or two, you probably want to hire another specialist to deal with the additional work.
The specialist tipping point
At a certain point in a company’s lifecycle, it will be hard to get along without specialists. Even the generalists you have hired will start to focus in on a particular area of the product. The product and the infrastructure that supports it gets much larger, and that introduces an interesting problem.
You started by hiring generalists who were capable of doing everything. That was possible because the infrastructure was small and it was easy to keep knowledge about everything in their heads. At a certain point, the infrastructure becomes so large that it’s nearly impossible for everyone to keep the whole thing in their heads. Trying to keep tabs on how all parts of the system are changing becomes impossible and so, necessarily, people start to specialize.
Specialization at this stage means keeping less of the system in your head, and it frees up engineers to be more effective. They end up needing to understand only the boundary conditions of a particular part of the system. If they need to know more than that for any reason, there’s someone to go to talk to who has that part of the system in their head.
You’ll know when you’ve hit this stage when people start to request to stay on particular projects longer or start coming up with new tasks on a particular part without prodding. It’s the, “I see five ways this could be better,” comment that indicates the beginning of specialization. Someone took the time to learn about this part of the system and now wants to continue working on it and making it better.
At this point, it’s easier to hire specialists because you already have them and it becomes harder to rationalize hiring generalists. As a company grows, teaching each engineer how to do their job or expecting them to learn something they’ve never done before on their own means a very slow start. At one company I worked at, it took engineers six months before they could be productive. This was the result of insisting on hiring generalists and also using proprietary instead of off-the-shelf systems. That meant we could never hire someone who already knew how something worked, we always had to hire in the hopes we could teach them. You just can’t afford that amount of lag when hiring.
That doesn’t mean engineers won’t get bored and occasionally want to jump into something completely different. That will still happen, but to a far lesser degree, and the organization can support a small number of people doing such a thing at this stage. It can’t support everyone continually shifting around to different parts of the system and needing to learn, from scratch, how to be effective in that part.
What about just hiring the best people?
The counter argument to hiring specialists is that the company really just wants to hire the best and the brightest and put them to work. I call this the Google ideal because it’s the way Google historically did hiring. Back when I interviewed with Google (circa 2006), they were the hot company that everyone wanted to work for. Just getting an interview was exciting. The interesting part was that they didn’t seem to care too much about what your specialty was. You also couldn’t apply for a particular position. Everyone who got hired would go into a pool and you’d find out what you were working on during your first day. So the idea was to hire the brightest people possible and find some place to put them to work. In short, the ultimate generalist approach.
I’m not sure if Google still hires this way or not, but I equate it to drafting the best player available in professional sports. If you’re not a sports fan, then here’s the little bit of knowledge you need to understand this analogy. Professional team sports in the United States have annual drafts in which the teams select amateur or international players for their teams. Basketball is the simplest to describe. At any given point in a game, a basketball team has five players on the court: two guards, two forwards, and a center. Each of these positions have different responsibilities and requirements. During the draft, many teams will look specifically for a player who plays a position that they need help with (the equivalent of a specialist). However, some teams opt for the “best player available”, which is to say that they don’t have a specific need for the position, or they aren’t sure what position the player will play, but they generally feel like the player is the most talented one available (the equivalent of a generalist).
Regardless of who the team selects, they are still limited to playing five players at a time. The goal is, therefore, to get the best center, the two best forwards, and the two best guards that you can get in order to be competitive. Refusing to see the difference between the requirements for each position and putting together a cohesive team means the whole team suffers. Basketball teams know this, and many times will pass over the player available if that player plays a position that the team already has covered with a good player.
Personally, I’m a big believer in hiring specialists when the size of your company and product allows you to do so. Continuing to hire generalists and training on-the-job becomes a scaling issue for a growing company and you invariably end up with an unbalanced team that’s not able to take on all of the new types of work that pop up.
Closing thoughts
I’ve come to believe that there’s a human tendency towards specialization. Our entire life is setup this way through the education process, which starts with general knowledge (math, literature, science, history) up into college where we are expected to pick a major or focus area. It’s natural that when you find something you enjoy doing, you want to do more of that and do so at the expense of other things that seem less interesting or enjoyable.
Early-stage companies definitely need generalists, and probably will for a decent amount of time until it’s possible to hire a lot of people. Generalists are well-suited to this situation, or really, any situation where there is a need to be able to move quickly between a group of disparate tasks. The tradeoff you’re making is in accepting “good enough” solutions for a lot of things rather than the best solution for a few. You hire generalists for their potential, for all the different things you imagine they can do for you.
You bring on specialists when “good enough” is no longer good enough. Sometimes that’s because of a big mess that need to be cleaned up, or sometimes it’s a natural evolution in the product where you need to deliver results quickly. In those cases, you need to bring in someone who already has the skills and knowledge to deliver. You hire specialists not for their potential to do other things, but for how they can meaningfully contribute right now.
And over the course of careers and companies, it’s not uncommon to see generalists become specialists. That’s natural as the size of the system and infrastructure grows and scales. Allowing people to become specialists helps everyone become more efficient, as they need to have less of the system in their heads in order to be effective at their job. That lets everyone move faster and focus more deeply on the problem at hand.
Knowing how and when to start transitioning into a specialist-based engineering organization is more of an art than a science, and I’m hopeful that this post shed some light on the decision.





July 14, 2014
Generalists and specialists: thoughts on hiring
In my career, I’ve worked at companies of all shapes and sizes. From the very tiny five-person failed startup WellFurnished to the 13,000-strong Yahoo to the around 1,000-person Box (my current employer). During that time, I’ve been a part of many different engineering organizations that have had very different philosophies about hiring engineers. I’ve interviewed and hired a lot of people in my time and have a pretty good track record at identifying good future colleagues.
Throughout my different jobs I’ve found that the primary distinguishing factor in hiring practices has come down to a single point: whether the company believes in hiring generalists or specialists. While I don’t believe there is one true way to build an engineering organization, I do believe that the size of the company and its stage of existence necessarily influences the approach.
Generalists and young companies
A generalist is someone who, by definition, has no particular specialty. They probably graduated with a computer science degree and is good doing a lot of what I’d describe as server-side activities: databases, infrastructure, builds, deploys, data manipulation and processing, and so on. Generalists don’t mind jumping from C++ to Python to Java in the course of their work, as many languages are similar enough that there aren’t huge barriers to making the transition. They are real workhorses, able to take on whatever is thrown at them.
Generalists tend to do a good but perhaps not great job on a lot of things and tend to struggle on things that require a different mode of thinking. For instance, many generalists struggle with taking on front-end or mobile work. The paradigm is so different that there’s not enough common ground to make these work well, and so those parts of the product tend to suffer a bit in the presence of generalists.
The early stages of a company are the ultimate expression of constrained resources. Even if you successfully raise money, it likely isn’t enough to hire all of the people you actually need. As such, anyone who joins the company is going to be expected to wear many hats and do many things. I signed on to WellFurnished to do the front-end and ended up setting up our infrastructure, source control, and build and deploy system. At that point, when looking for help, I mostly looked for generalists who could hop in and help in any number of places.
Young companies don’t have the luxury of hiring people who can only do one thing or a small subset of things. There’s too much work to do and not enough people to do it. Generalists are the way that the business gets off the ground and makes something works. Everyone needs to be working on something all of the time or you’re wasting a very limited resource: money.
At this stage, there’s also a certain pragmatism to the technical approach. The entire system is relatively small and so it’s possible (and necessary) for each engineer to understand each part of the system. Being able to keep the entire system in your head is key at this point, because everyone needs to be able to do just about everything.
Introducing specialists
Specialists, on the other hand, are people who excel at a particular type of thing. They have made room in their brains for deep knowledge of a particular area and, in doing so, have necessarily forgotten (intentionally or not) some of the things that generalists know top-of-mind. What specialists bring to the table is a level of excellence in something specific. They have devoted their career to focusing narrowly on something and, as a result, are much better at that thing than a generalist could ever be.
Early on at a company, generalists create a lot of “good enough” solutions. That’s not to say this is a bad strategy, it’s just a fact of how companies grow. The “good enough” solutions are, as the name suggestions, good enough to get the company to its next stage growth. Sometimes it’s good enough to get the company through two or three stages of growth. But eventually, “good enough” won’t be good enough anymore, and that’s when you need to start hiring specialists.
Not good enough comes in many forms. The most obvious is in the front-end: every company I’ve been at that focused on hiring generalists has had a terrible time getting any sort of quality front-end built. Designers get frustrated because the engineers can’t figure out how to make what they designed, and product managers are frustrated because the front-end is a key differentiator to end users. At that point, someone starts asking if it’s time to hire someone who “really knows this stuff.”
This is often a controversial topic for smaller companies that are growing into larger ones. The main arguments against hiring specialists tend to be:
We don’t know how. The interview process is tailored for generalists. That lends itself to interview processes filled with general-purpose computer science knowledge in an effort to determine if the candidate is “smart.” There’s algorithms and data structures and discussions of complexity – all designed not to test individual skills but rather to test concepts and ideas that should be transferable to any programming language. A generalist should, after all, be able to just pick up another language so long as the concepts are solid. Once a company is used to labeling candidates as “smart” or not based on this type of interview process, it’s very hard to make a switch. In fact, “smart” is a dynamic term that doesn’t apply equally to everyone. But how can you properly vet a specialist if that specialization isn’t represented at the company?
It creates resource allocation problems. One of the theories behind hiring generalists is that you’ll have a small army of roughly-equivalent resources to assign to projects. If everyone is capable of doing everything, you have ultimate flexibility in resourcing projects. You don’t have to wait for Jim to come free or for Mary to finish up her last project. If an engineer becomes available, you assign them to the next thing. Specialists, by definition, are limited in what you can assign them to work on. That fundamentally shifts how resource allocation works within the engineering organization: all of a sudden there’s one person who can only do a subset of the work. The whole system is thrown into an unstable state because of this one discrepancy.
If you’re a specialist reading this list, you’re probably thinking, “those are bullshit reasons.” If you’re a generalist reading this list, you’re probably thinking, “well duh, obviously.” So I’ll split the difference and say that these concerns are real and valid, however, they are far from unsolvable. Many companies have tread this path and have come out successful. The trouble is always getting that first specialist in the door to prove the system can work.
Do we really need a specialist?
Whether or not you really need a specialist tends to come down to how dire your situation is and generally falls into one of two categories:
Stuff is really broken. Unfortunately, this is the more common scenario. After months or years of hacking away at something, things are such a mess that “good enough” is now considered “horrible”. You need someone who already knows how to fix the problem.
Moving into a new area. A lot of companies will want to hire specialists when they’re moving into a new area of business and need to execute quickly. For instance, introducing a mobile application when they’ve only done web applications, or vice versa. This is a nice opportunity for the specialist because they get a blank slate to show they know their stuff. Unfortunately, these opportunities don’t come along very often.
The first situation, things becoming a big mess, is pretty much how I’ve made my career both as an employee and as a consultant. The second situation was most recently experienced by mobile developers as all companies rushed to create mobile apps.
The question of whether you real need a specialist or not can also be answered by looking at the current resource allocation. If you see the same part of the system constantly needing attention (i.e., the web front-end or the mobile app), then chances are the generalists are no longer cutting it.
Hiring a specialist
Eventually, every successful company will hire their first specialist – it’s a virtual certainty. The first step is to figure out how to hire that specialist. You need to accept that your current interview process probably doesn’t apply. On top of that, specialists tend to get frustrated with questions that have nothing to do with what they’re good at. So how do you interview for a specialist when your company doesn’t have that specialization?
While you’re company doesn’t have any specialization, it does have people who have worked on the specific problems you want the specialist to work on. Those are the people who should be conducting the interview. The simplest way to go forward is to discuss the current problems you’re having and ask candidates how they would go about solving them. This isn’t about getting free work from random people, as it’s likely impossible to solve these problems completely during the course of an interview. Rather, it’s about getting the candidates to teach you about the context of the problem and understanding their thought process. Good specialists will be able to tell you the area of the problem and how they would go about investigating and potentially fixing it.
This ability to clearly communicate to people outside of their specialization is really important for a first specialist hire since that’s what they’ll be doing all the time. Because no one else will know exactly what they’re doing, you need to be able to trust the specialist to communicate clearly and in a way that everyone can understand. In the end, understanding how the candidate will address the problem and agreeing that it makes sense is the best way to make this first hire.
The second part of the problem, resource allocation, tends to fix itself. Many generalist-minded engineering VPs fear that the specialist will be left without enough to do such that they become a money sink. In practice, there’s usually enough work for the specialist to focus on in the beginning that this isn’t a big issue. Either cleaning up a mess or creating a completely new product means that the specialist will have plenty to keep them busy for a decent amount of time. After that point, it’s typically the case that once an engineering team has developed a competence in something, they want to add more to it. The web application starts needing new end-user features and the mobile apps needs some new functionality. Oftentimes, you’ll find that within a year or two, you probably want to hire another specialist to deal with the additional work.
The specialist tipping point
At a certain point in a company’s lifecycle, it will be hard to get along without specialists. Even the generalists you have hired will start to focus in on a particular area of the product. The product and the infrastructure that supports it gets much larger, and that introduces an interesting problem.
You started by hiring generalists who were capable of doing everything. That was possible because the infrastructure was small and it was easy to keep knowledge about everything in their heads. At a certain point, the infrastructure becomes so large that it’s nearly impossible for everyone to keep the whole thing in their heads. Trying to keep tabs on how all parts of the system are changing becomes impossible and so, necessarily, people start to specialize.
Specialization at this stage means keeping less of the system in your head, and it frees up engineers to be more effective. They end up needing to understand only the boundary conditions of a particular part of the system. If they need to know more than that for any reason, there’s someone to go to talk to who has that part of the system in their head.
You’ll know when you’ve hit this stage when people start to request to stay on particular projects longer or start coming up with new tasks on a particular part without prodding. It’s the, “I see five ways this could be better,” comment that indicates the beginning of specialization. Someone took the time to learn about this part of the system and now wants to continue working on it and making it better.
At this point, it’s easier to hire specialists because you already have them and it becomes harder to rationalize hiring generalists. As a company grows, teaching each engineer how to do their job or expecting them to learn something they’ve never done before on their own means a very slow start. At one company I worked at, it took engineers six months before they could be productive. This was the result of insisting on hiring generalists and also using proprietary instead of off-the-shelf systems. That meant we could never hire someone who already knew how something worked, we always had to hire in the hopes we could teach them. You just can’t afford that amount of lag when hiring.
That doesn’t mean engineers won’t get bored and occasionally want to jump into something completely different. That will still happen, but to a far lesser degree, and the organization can support a small number of people doing such a thing at this stage. It can’t support everyone continually shifting around to different parts of the system and needing to learn, from scratch, how to be effective in that part.
What about just hiring the best people?
The counter argument to hiring specialists is that the company really just wants to hire the best and the brightest and put them to work. I call this the Google ideal because it’s the way Google historically did hiring. Back when I interviewed with Google (circa 2006), they were the hot company that everyone wanted to work for. Just getting an interview was exciting. The interesting part was that they didn’t seem to care too much about what your specialty was. You also couldn’t apply for a particular position. Everyone who got hired would go into a pool and you’d find out what you were working on during your first day. So the idea was to hire the brightest people possible and find some place to put them to work. In short, the ultimate generalist approach.
I’m not sure if Google still hires this way or not, but I equate it to drafting the best player available in professional sports. If you’re not a sports fan, then here’s the little bit of knowledge you need to understand this analogy. Professional team sports in the United States have annual drafts in which the teams select amateur or international players for their teams. Basketball is the simplest to describe. At any given point in a game, a basketball team has five players on the court: two guards, two forwards, and a center. Each of these positions have different responsibilities and requirements. During the draft, many teams will look specifically for a player who plays a position that they need help with (the equivalent of a specialist). However, some teams opt for the “best player available”, which is to say that they don’t have a specific need for the position, or they aren’t sure what position the player will play, but they generally feel like the player is the most talented one available (the equivalent of a generalist).
Regardless of who the team selects, they are still limited to playing five players at a time. The goal is, therefore, to get the best center, the two best forwards, and the two best guards that you can get in order to be competitive. Refusing to see the difference between the requirements for each position and putting together a cohesive team means the whole team suffers. Basketball teams know this, and many times will pass over the player available if that player plays a position that the team already has covered with a good player.
Personally, I’m a big believer in hiring specialists when the size of your company and product allows you to do so. Continuing to hire generalists and training on-the-job becomes a scaling issue for a growing company and you invariably end up with an unbalanced team that’s not able to take on all of the new types of work that pop up.
Closing thoughts
I’ve come to believe that there’s a human tendency towards specialization. Our entire life is setup this way through the education process, which starts with general knowledge (math, literature, science, history) up into college where we are expected to pick a major or focus area. It’s natural that when you find something you enjoy doing, you want to do more of that and do so at the expense of other things that seem less interesting or enjoyable.
Early-stage companies definitely need generalists, and probably will for a decent amount of time until it’s possible to hire a lot of people. Generalists are well-suited to this situation, or really, any situation where there is a need to be able to move quickly between a group of disparate tasks. The tradeoff you’re making is in accepting “good enough” solutions for a lot of things rather than the best solution for a few. You hire generalists for their potential, for all the different things you imagine they can do for you.
You bring on specialists when “good enough” is no longer good enough. Sometimes that’s because of a big mess that need to be cleaned up, or sometimes it’s a natural evolution in the product where you need to deliver results quickly. In those cases, you need to bring in someone who already has the skills and knowledge to deliver. You hire specialists not for their potential to do other things, but for how they can meaningfully contribute right now.
And over the course of careers and companies, it’s not uncommon to see generalists become specialists. That’s natural as the size of the system and infrastructure grows and scales. Allowing people to become specialists helps everyone become more efficient, as they need to have less of the system in their heads in order to be effective at their job. That lets everyone move faster and focus more deeply on the problem at hand.
Knowing how and when to start transitioning into a specialist-based engineering organization is more of an art than a science, and I’m hopeful that this post shed some light on the decision.





June 3, 2014
My ECMAScript 7 wishlist
With ECMAScript 6 now feature complete, any further changes to the core of JavaScript will happen in ECMAScript 7. I’m pretty excited about the changes coming in ECMAScript 6 and there are already some great ECMAScript 7 features such as Object.observe() and asynchronous functions. While the development of ECMAScript 7 continues, I just wanted to share my personal wishlist of things that would make writing JavaScript even better and are (seemingly) within the scope of consideration for ECMAScript 7.
Some notes about the wishlist items:
I haven’t found a good source of already-scheduled ECMAScript 7 features, so I don’t know if any of these are already on the roadmap or not.
I don’t actually care what the names of things are, I just care about the functionality.
I’m no expert in syntax. It’s entirely possible I suggested something here that isn’t feasible.
Arrays
I recently came to realize that I spend an inordinate amount of time working with arrays in JavaScript, moreso than anything else. I’ve had a growing list of annoying things about working with arrays that have been partially solved in ECMAScript 5 and 6. However, there still seems to be some low-handing fruit.
Array.prototype.last(), Array.prototype.first()
The number of times I write something like items[items.length - 1] each week drives me crazy. I just want a last() method that does it for me. The native equivalent of this:
Array.prototype.last = function() {
return this[this.length - 1];
};
While I check the last item of arrays frequently, I also check the first item frequently. So I’d love to have first() as well:
Array.prototype.first = function() {
return this[0];
};
With these two methods, a lot of my code would look cleaner:
//before
if (items[0] === "(" && items[items.length - 1] === ")") {
// do something
}
// after
if (items.first() === "(" && items.last() === ")") {
// do something
}
Array.prototype.isEmpty()
Another thing I do with arrays a lot is check to see if it’s empty by comparing the length to zero. I’d much rather have a method to improve readability. Something like this:
Array.prototype.isEmpty = function() {
return this.length === 0;
}
Function.empty
I find myself using empty functions frequently, especially in tests and callback-oriented functions where I don’t actually care to wait for the results. That means I usually write things like:
someAsyncMethod(function() {
// noop
});
The // noop comment is there to make sure people understand I intentionally left this function empty. I’d much rather there be a predefined empty function that I can reuse whenever I want a throwaway function, such as:
someAsyncMethod(Function.empty);
// where...
Object.defineProperty(Function, "empty", {
value: () => {},
writable: false,
configurable: false,
enumerable: true
};
Object.deepPreventExtensions(), Object.deepSeal(), Object.deepFreeze()
ECMAScript 5 added Object.preventExtensions(), Object.seal(), and Object.freeze(). These serve to protect objects from certain types of modification, which is fantastic, except that these are shallow operations. For instance:
var data = {
subdata: {
type: "js"
}
};
Object.freeze(data);
data.subdata = {}; // fails silently in nonstrict mode
data.subdata.type = "css"; // succeeds
This is working as intended, data.subdata cannot be overwritten but data.subdata.type can be since Object.freeze() only freezes the properties of the object that is passed. In most cases, that’s okay, but I’ve found myself needing to apply object protection deeply, and it would be great to have official methods that did this.
My primary use case is in reading in a JSON configuration and wanting to protect it throughout the lifetime of the application. It’s possible to implement this fairly easily in ECMAScript 6:
Object.deepPreventExtensions = function(object) {
// for avoiding circular references
var handled = new WeakSet();
// recursive function
function deepPreventExtensions(object) {
// handle first level
Object.preventExtensions(object);
handled.add(object);
Object.keys(object).filter(function(key) {
// get keys for objects not already handled
return object[key] && (typeof object[key] === 'object') && !handled.has(object[key]);
}).forEach(function(key) {
Object.deepPreventExtensions(object[key]);
});
}
deepPreventExtensions(object);
};
The only tricky part is handling circular references, but that is made somewhat easier by using a WeakSet to track already-handled objects. The same basic pattern can be applied for Object.deepSeal() and Object.deepFreeze().
Defensive objects
I recently wrote a post about defensive objects. As a refresher, defensive objects are those that throw an error when you try to read a property that doesn’t exist. This is the way objects work in type safe languages and is the last missing capability for accurately creating classes in JavaScript that behave as they would in other languages.
Today, you can get pretty close:
class Person {
constructor(name) {
this.name = name;
Object.seal(this);
}
}
Using the ECMAScript 6 class syntax plus Object.seal(), you’re able to create an object that can’t have its properties removed or new properties added. However, accessing a nonexistent property will still just return undefined:
var me = new Person("Nicholas");
console.log(me.nme); // unfortunate typo, returns undefined
Because the property nme doesn’t exist, it returns undefined when you try to access it. I recently spent a half hour tracking down a bug that was a typo of this nature and wished I had a way to prevent it from happening.
Adding this behavior would bring object properties inline with variables in terms of what will happen when you try to access something that doesn’t exist. An error is thrown when you try to read an undeclared variable; I’d like that same behavior when you try to read an undeclared property.
I propose a method that is similar to Object.preventExtensions(), perhaps called Object.preventUndeclaredGet() (probably not the best name) that would set an internal property on an object changing the [[Get]] behavior to throw an error when the given property doesn’t exist. For example:
class Person {
constructor(name) {
this.name = name;
Object.seal(this);
Object.preventUndeclaredGet(this);
}
}
var me = new Person("Nicholas");
console.log(me.name); // "Nicholas"
console.log(me.nme); // throws error
Adding this capability allows you to create classes that correctly mimic classes in other languages. Also, if you don’t seal the object, you can add new properties whenever you want; as long as you set the property value before reading it, no error will occur.
Custom descriptor attributes
Property descriptors seem like a great way to add meta information to properties except that you cannot add unknown properties. JavaScript always returns only the spec-defined attributes when you try to store a custom piece of information:
var me = {};
Object.defineProperty(me, "name", {
value: "Nicholas"
type: "string"
});
var descriptor = Object.getOwnPropertyDescriptor(me, "name");
console.log(descriptor.value); // "Nicholas"
console.log(descriptor.type); // "undefined"
To me, the property descriptor is a great possible location for storing information related to a particular property. Besides the implications for storing type hints, you could also store relevant information about validation, data bindings, or more.
It wouldn’t make sense to allow just any arbitrary attributes on the descriptor, as the language might need to add more in the future. However, adding a single property that is designed for custom information could work. For instance, what if the spec declared a property called meta to contain user-defined information. That meta would be stored and could later be retrieved exactly as-is, without the possibility of affecting the other property descriptor values or risk naming collisions with future property descriptor attributes. For example:
var me = {};
Object.defineProperty(me, "name", {
value: "Nicholas"
meta: {
type: "string"
}
});
var descriptor = Object.getOwnPropertyDescriptor(me, "name");
console.log(descriptor.value); // "Nicholas"
console.log(descriptor.meta.type); // "string"
Lightweight traits
In many ways, JavaScript has supported traits for a long time through the use of mixins. Traits are really the same thing: objects that provide a set of methods intended to be applied to another object. The Object.assign() method was added in ECMAScript 6 to aid in this endeavor. However, it can get quite messy to use this approach:
var trait1 = {
method1: function() {}
};
var trait2 = {
method2: function() {}
};
function MyObject() {
// ...
}
Object.assign(MyObject.prototype, trait1, trait2, {
method3: function() {}
});
There’s no way to easily do the same thing with ECMAScript 6 classes, so you’d be stuck calling Object.assign() in the constructor and applying it to each instance.
What I’d like to propose is some syntactic sugar to make this easier using object literals and classes. For object literals, it would look like this:
function MyObject() {
// ...
}
// lightweight traits
MyObject.prototype = {
use trait1,
use trait2,
method3: function() {}
};
// desugars to
MyObject.prototype = Object.assign({}, trait1, trait2, {
method3: function() {}
});
A similar syntax can be used in ECMAScript 6 classes to specify traits for the prototype:
class MyObject {
use trait1;
use trait2;
constructor() {}
method3() {}
}
// desugars to
function MyObject() {
// ...
}
Object.assign(MyObject.prototype, trait1, trait2, {
method3: function() {}
});
It’s entirely possible that Object.assign() should actually be something else, perhaps something that also calls toMethod() so the super binding is correct, but I think this example illustrates my point.
Conclusion
I’m very excited to see where ECMAScript 7 is headed and hope that some of these ideas are worthwhile enough to pursue. Even if they aren’t, ECMAScript 6 is such a superior upgrade from ECMAScript 5 that I’m sure ECMAScript 7 will be a really great set of changes as well.





June 2, 2014
My ECMAScript 7 wishlist
With ECMAScript 6 now feature complete, any further changes to the core of JavaScript will happen in ECMAScript 7. I’m pretty excited about the changes coming in ECMAScript 6 and there are already some great ECMAScript 7 features such as Object.observe() and asynchronous functions. While the development of ECMAScript 7 continues, I just wanted to share my personal wishlist of things that would make writing JavaScript even better and are (seemingly) within the scope of consideration for ECMAScript 7.
Some notes about the wishlist items:
I haven’t found a good source of already-scheduled ECMAScript 7 features, so I don’t know if any of these are already on the roadmap or not.
I don’t actually care what the names of things are, I just care about the functionality.
I’m no expert in syntax. It’s entirely possible I suggested something here that isn’t feasible.
Arrays
I recently came to realize that I spend an inordinate amount of time working with arrays in JavaScript, moreso than anything else. I’ve had a growing list of annoying things about working with arrays that have been partially solved in ECMAScript 5 and 6. However, there still seems to be some low-handing fruit.
Array.prototype.last(), Array.prototype.first()
The number of times I write something like items[items.length - 1] each week drives me crazy. I just want a last() method that does it for me. The native equivalent of this:
Array.prototype.last = function() {
return this[this.length - 1];
};
While I check the last item of arrays frequently, I also check the first item frequently. So I’d love to have first() as well:
Array.prototype.first = function() {
return this[0];
};
With these two methods, a lot of my code would look cleaner:
//before
if (items[0] === "(" && items[items.length - 1] === ")") {
// do something
}
// after
if (items.first() === "(" && items.last() === ")") {
// do something
}
Array.prototype.isEmpty()
Another thing I do with arrays a lot is check to see if it’s empty by comparing the length to zero. I’d much rather have a method to improve readability. Something like this:
Array.prototype.isEmpty = function() {
return this.length === 0;
}
Function.empty
I find myself using empty functions frequently, especially in tests and callback-oriented functions where I don’t actually care to wait for the results. That means I usually write things like:
someAsyncMethod(function() {
// noop
});
The // noop comment is there to make sure people understand I intentionally left this function empty. I’d much rather there be a predefined empty function that I can reuse whenever I want a throwaway function, such as:
someAsyncMethod(Function.empty);
// where...
Object.defineProperty(Function, "empty", {
value: () => {},
writable: false,
configurable: false,
enumerable: true
};
Object.deepPreventExtensions(), Object.deepSeal(), Object.deepFreeze()
ECMAScript 5 added Object.preventExtensions(), Object.seal(), and Object.freeze(). These serve to protect objects from certain types of modification, which is fantastic, except that these are shallow operations. For instance:
var data = {
subdata: {
type: "js"
}
};
Object.freeze(data);
data.subdata = {}; // fails silently in nonstrict mode
data.subdata.type = "css"; // succeeds
This is working as intended, data.subdata cannot be overwritten but data.subdata.type can be since Object.freeze() only freezes the properties of the object that is passed. In most cases, that’s okay, but I’ve found myself needing to apply object protection deeply, and it would be great to have official methods that did this.
My primary use case is in reading in a JSON configuration and wanting to protect it throughout the lifetime of the application. It’s possible to implement this fairly easily in ECMAScript 6:
Object.deepPreventExtensions = function(object) {
// for avoiding circular references
var handled = new WeakSet();
// recursive function
function deepPreventExtensions(object) {
// handle first level
Object.preventExtensions(object);
handled.add(object);
Object.keys(object).filter(function(key) {
// get keys for objects not already handled
return object[key] && (typeof object[key] === 'object') && !handled.has(object[key]);
}).forEach(function(key) {
Object.deepPreventExtensions(object[key]);
});
}
deepPreventExtensions(object);
};
The only tricky part is handling circular references, but that is made somewhat easier by using a WeakSet to track already-handled objects. The same basic pattern can be applied for Object.deepSeal() and Object.deepFreeze().
Defensive objects
I recently wrote a post about defensive objects. As a refresher, defensive objects are those that throw an error when you try to read a property that doesn’t exist. This is the way objects work in type safe languages and is the last missing capability for accurately creating classes in JavaScript that behave as they would in other languages.
Today, you can get pretty close:
class Person {
constructor(name) {
this.name = name;
Object.seal(this);
}
}
Using the ECMAScript 6 class syntax plus Object.seal(), you’re able to create an object that can’t have its properties removed or new properties added. However, accessing a nonexistent property will still just return undefined:
var me = new Person("Nicholas");
console.log(me.nme); // unfortunate typo, returns undefined
Because the property nme doesn’t exist, it returns undefined when you try to access it. I recently spent a half hour tracking down a bug that was a typo of this nature and wished I had a way to prevent it from happening.
Adding this behavior would bring object properties inline with variables in terms of what will happen when you try to access something that doesn’t exist. An error is thrown when you try to read an undeclared variable; I’d like that same behavior when you try to read an undeclared property.
I propose a method that is similar to Object.preventExtensions(), perhaps called Object.preventUndeclaredGet() (probably not the best name) that would set an internal property on an object changing the [[Get]] behavior to throw an error when the given property doesn’t exist. For example:
class Person {
constructor(name) {
this.name = name;
Object.seal(this);
Object.preventUndeclaredGet(this);
}
}
var me = new Person("Nicholas");
console.log(me.name); // "Nicholas"
console.log(me.nme); // throws error
Adding this capability allows you to create classes that correctly mimic classes in other languages. Also, if you don’t seal the object, you can add new properties whenever you want; as long as you set the property value before reading it, no error will occur.
Custom descriptor attributes
Property descriptors seem like a great way to add meta information to properties except that you cannot add unknown properties. JavaScript always returns only the spec-defined attributes when you try to store a custom piece of information:
var me = {};
Object.defineProperty(me, "name", {
value: "Nicholas"
type: "string"
});
var descriptor = Object.getOwnPropertyDescriptor(me, "name");
console.log(descriptor.value); // "Nicholas"
console.log(descriptor.type); // "undefined"
To me, the property descriptor is a great possible location for storing information related to a particular property. Besides the implications for storing type hints, you could also store relevant information about validation, data bindings, or more.
It wouldn’t make sense to allow just any arbitrary attributes on the descriptor, as the language might need to add more in the future. However, adding a single property that is designed for custom information could work. For instance, what if the spec declared a property called meta to contain user-defined information. That meta would be stored and could later be retrieved exactly as-is, without the possibility of affecting the other property descriptor values or risk naming collisions with future property descriptor attributes. For example:
var me = {};
Object.defineProperty(me, "name", {
value: "Nicholas"
meta: {
type: "string"
}
});
var descriptor = Object.getOwnPropertyDescriptor(me, "name");
console.log(descriptor.value); // "Nicholas"
console.log(descriptor.meta.type); // "string"
Lightweight traits
In many ways, JavaScript has supported traits for a long time through the use of mixins. Traits are really the same thing: objects that provide a set of methods intended to be applied to another object. The Object.assign() method was added in ECMAScript 6 to aid in this endeavor. However, it can get quite messy to use this approach:
var trait1 = {
method1: function() {}
};
var trait2 = {
method2: function() {}
};
function MyObject() {
// ...
}
Object.assign(MyObject.prototype, trait1, trait2, {
method3: function() {}
});
There’s no way to easily do the same thing with ECMAScript 6 classes, so you’d be stuck calling Object.assign() in the constructor and applying it to each instance.
What I’d like to propose is some syntactic sugar to make this easier using object literals and classes. For object literals, it would look like this:
function MyObject() {
// ...
}
// lightweight traits
MyObject.prototype = {
use trait1,
use trait2,
method3: function() {}
};
// desugars to
MyObject.prototype = Object.assign({}, trait1, trait2, {
method3: function() {}
});
A similar syntax can be used in ECMAScript 6 classes to specify traits for the prototype:
class MyObject {
use trait1;
use trait2;
constructor() {}
method3() {}
}
// desugars to
function MyObject() {
// ...
}
Object.assign(MyObject.prototype, trait1, trait2, {
method3: function() {}
});
It’s entirely possible that Object.assign() should actually be something else, perhaps something that also calls toMethod() so the super binding is correct, but I think this example illustrates my point.
Conclusion
I’m very excited to see where ECMAScript 7 is headed and hope that some of these ideas are worthwhile enough to pursue. Even if they aren’t, ECMAScript 6 is such a superior upgrade from ECMAScript 5 that I’m sure ECMAScript 7 will be a really great set of changes as well.





May 27, 2014
An open letter to the FCC regarding net neutrality
Dear Chairman Wheeler,
I’m writing to you as a citizen who is deeply concerned about the direction the FCC may take with regards to ISPs. As both a consumer and a technology worker, I rely on the Internet not only as a source of entertainment and information, but also a way to communicate with colleagues and customers. As someone who is fighting Lyme disease, I spend most of my time at home, with the Internet as my primary means of communication and the only means by which I’m able to remain employed. In an average day, I log into my company’s virtual private network (VPN) to securely do my work over the Internet, and later in the day I may watch something on Netflix. Suffice to say, the Internet is an important part of my life.
I’d like to go on record by saying that I think ISPs should be able to make money. They put a lot of money into building out an important piece of infrastructure that benefits all citizens and they should be able to recoup their investments and make money in the process. I also believe that ISPs have a right, and maybe even a responsibility, to ensure that all traffic is given a fair chance to make it through their network. This necessarily means watching out for services that are using an inordinate amount of bandwidth that may prevent other data from making it through. I want ISPs to protect customers from this situation.
I’m aware that Netflix traffic is growing to be a significant portion of all Internet traffic. I realize how this can affect ISPs financially and also how it can negatively affect other types of Internet traffic. If I was unable to log into my bank or my work VPN because too many people were watching House of Cards, I’d be pretty upset.
At the same time, it frightens me to see the way that ISPs such as Comcast have dealt with this situation. Instead of being open about it, they started throttling the Netflix service, leaving customers confused and angry. When consumers pay for Internet service to their homes, there is an implicit guarantee of delivering all traffic the same way. We are paying for the gateway to the public Internet and then we expect the ISP to get out of the way so we can have the content we request. By throttling Netflix traffic, Comcast broke this implicit agreement, harming customers in the process.
The ISPs repeatedly talk about having a “fast lane” option, where services can pay extra money for the right to have faster speeds. In reality, what ISPs have done is not offer a new fast lane, but instead, they have added a new slow lane and shifted traffic to it. The charge, therefore, is to get back into the “normal” lane that they were on before. Consumers, in the meantime, are confused as to why they are paying for a 1.5mbps connection that is delivering only 256kbps for one or more services.
If this trend continues, it will further confuse the consumer market because each ISP will be free to transmit data from any service at any speed they so desire. Further, without strict guidelines, there is nothing preventing ISPs from arbitrarily shifting traffic into the slow lane whenever they choose, effectively turning the Internet into a toll bridge where if you don’t pay, your Internet business suffers.
You’ve probably heard the argument that ISPs will self-regulate, because if consumers get too frustrated, they will switch ISPs. In reality, few consumers have true choice when it comes to ISPs. In many places, the choices are between two companies with near-monopoly power: the cable and telephone companies. In Mountain View, California, where I live, my choices are Comcast and AT&T. Having a choice between two gigantic companies that couldn’t care less if I was a customer isn’t really a choice. What’s more, because these two compete on a national level as well as local, if one of them behaves in such a way that makes more money, the other is likely to follow. If one sees the other effectively extorting millions of dollars from a content provider, the other is likely to follow suit. After all, the number of customers that would have to switch ISPs to generate the same amount of money is extraordinarily high. And when both ISPs in a region are throttling traffic arbitrarily to extort millions of dollar from content providers, what other choice do I have?
What’s to prevent ISPs from throttling VPN traffic? Or traffic to delivery services that disabled Americans rely on? The one thing we all know for sure about capitalism is that monopolistic companies do not act with the best interests of the consumer in mind. These large ISPs are achingly close to being monopolies, and they cannot be trusted to self-regulate.
ISPs need government regulation to ensure that fair pricing models are applied to Internet traffic and that ISPs are not allowed to decide which traffic gets which speed without oversight. We need rules that will both protect consumers from the deceptive ISP practices of throttling certain traffic while also allowing ISPs to charge more when a particular service is taking up an inordinate amount of bandwidth.
One such solution would be to disallow bandwidth throttling or extra charges for any service that falls beneath a particular percentage of total ISP monthly bandwidth use. This would protect new businesses and popular web sites from extra charges, as well as encouraging existing services to more closely monitor their bandwidth usage. Once a particular service’s bandwidth usage crosses the percentage threshold, there should be a buffer zone between that threshold and the one at which the service must pay more to be switched to a “fast lane”. The intent of that buffer zone is so that ISPs have time to inform the service of their bandwidth usage before new charges kick in, and services have time to either prepare to pay more or to adjust their services to use less bandwidth.
This is just one solution of many that will be available to you. The key aspects of this solution, and of any truly fair solution are:
ISP transparency about when new charges will apply
Regulations establishing what traffic may not be throttled or charged more
Protecting consumers for the near-monopolistic behavior of ISPs in many parts of the country
Mr. Chairman, I know my voice is just one of the many you have and will continue to hear during the next few months, but I hope you will consider the importance of regulating what has become an important piece of our country’s infrastructure. We cannot let ISPs continue to dictate terms based on their own preferences without negatively affecting consumers and businesses that rely on the Internet.
Sincerely,
Nicholas Zakas





May 26, 2014
An open letter to the FCC regarding net neutrality
Dear Chairman Wheeler,
I’m writing to you as a citizen who is deeply concerned about the direction the FCC may take with regards to ISPs. As both a consumer and a technology worker, I rely on the Internet not only as a source of entertainment and information, but also a way to communicate with colleagues and customers. As someone who is fighting Lyme disease, I spend most of my time at home, with the Internet as my primary means of communication and the only means by which I’m able to remain employed. In an average day, I log into my company’s virtual private network (VPN) to securely do my work over the Internet, and later in the day I may watch something on Netflix. Suffice to say, the Internet is an important part of my life.
I’d like to go on record by saying that I think ISPs should be able to make money. They put a lot of money into building out an important piece of infrastructure that benefits all citizens and they should be able to recoup their investments and make money in the process. I also believe that ISPs have a right, and maybe even a responsibility, to ensure that all traffic is given a fair chance to make it through their network. This necessarily means watching out for services that are using an inordinate amount of bandwidth that may prevent other data from making it through. I want ISPs to protect customers from this situation.
I’m aware that Netflix traffic is growing to be a significant portion of all Internet traffic. I realize how this can affect ISPs financially and also how it can negatively affect other types of Internet traffic. If I was unable to log into my bank or my work VPN because too many people were watching House of Cards, I’d be pretty upset.
At the same time, it frightens me to see the way that ISPs such as Comcast have dealt with this situation. Instead of being open about it, they started throttling the Netflix service, leaving customers confused and angry. When consumers pay for Internet service to their homes, there is an implicit guarantee of delivering all traffic the same way. We are paying for the gateway to the public Internet and then we expect the ISP to get out of the way so we can have the content we request. By throttling Netflix traffic, Comcast broke this implicit agreement, harming customers in the process.
The ISPs repeatedly talk about having a “fast lane” option, where services can pay extra money for the right to have faster speeds. In reality, what ISPs have done is not offer a new fast lane, but instead, they have added a new slow lane and shifted traffic to it. The charge, therefore, is to get back into the “normal” lane that they were on before. Consumers, in the meantime, are confused as to why they are paying for a 1.5mbps connection that is delivering only 256kbps for one or more services.
If this trend continues, it will further confuse the consumer market because each ISP will be free to transmit data from any service at any speed they so desire. Further, without strict guidelines, there is nothing preventing ISPs from arbitrarily shifting traffic into the slow lane whenever they choose, effectively turning the Internet into a toll bridge where if you don’t pay, your Internet business suffers.
You’ve probably heard the argument that ISPs will self-regulate, because if consumers get too frustrated, they will switch ISPs. In reality, few consumers have true choice when it comes to ISPs. In many places, the choices are between two companies with near-monopoly power: the cable and telephone companies. In Mountain View, California, where I live, my choices are Comcast and AT&T. Having a choice between two gigantic companies that couldn’t care less if I was a customer isn’t really a choice. What’s more, because these two compete on a national level as well as local, if one of them behaves in such a way that makes more money, the other is likely to follow. If one sees the other effectively extorting millions of dollars from a content provider, the other is likely to follow suit. After all, the number of customers that would have to switch ISPs to generate the same amount of money is extraordinarily high. And when both ISPs in a region are throttling traffic arbitrarily to extort millions of dollar from content providers, what other choice do I have?
What’s to prevent ISPs from throttling VPN traffic? Or traffic to delivery services that disabled Americans rely on? The one thing we all know for sure about capitalism is that monopolistic companies do not act with the best interests of the consumer in mind. These large ISPs are achingly close to being monopolies, and they cannot be trusted to self-regulate.
ISPs need government regulation to ensure that fair pricing models are applied to Internet traffic and that ISPs are not allowed to decide which traffic gets which speed without oversight. We need rules that will both protect consumers from the deceptive ISP practices of throttling certain traffic while also allowing ISPs to charge more when a particular service is taking up an inordinate amount of bandwidth.
One such solution would be to disallow bandwidth throttling or extra charges for any service that falls beneath a particular percentage of total ISP monthly bandwidth use. This would protect new businesses and popular web sites from extra charges, as well as encouraging existing services to more closely monitor their bandwidth usage. Once a particular service’s bandwidth usage crosses the percentage threshold, there should be a buffer zone between that threshold and the one at which the service must pay more to be switched to a “fast lane”. The intent of that buffer zone is so that ISPs have time to inform the service of their bandwidth usage before new charges kick in, and services have time to either prepare to pay more or to adjust their services to use less bandwidth.
This is just one solution of many that will be available to you. The key aspects of this solution, and of any truly fair solution are:
ISP transparency about when new charges will apply
Regulations establishing what traffic may not be throttled or charged more
Protecting consumers for the near-monopolistic behavior of ISPs in many parts of the country
Mr. Chairman, I know my voice is just one of the many you have and will continue to hear during the next few months, but I hope you will consider the importance of regulating what has become an important piece of our country’s infrastructure. We cannot let ISPs continue to dictate terms based on their own preferences without negatively affecting consumers and businesses that rely on the Internet.
Sincerely,
Nicholas Zakas





May 6, 2014
URLs are already dead
Last week, there was a fair bit of furor when Jake Archibald wrote an article[1] describing an experimental feature in Chrome that hides all but the domain name of the URL you’re on. The idea is very similar to what already happens in the iOS 7 version of Safari: once navigation is underway, the URL is hidden and only the domain name is visible in the location bar. If you want to get to the full URL, then you either click or set focus back to the location bar (in Chrome, you click the domain name).
I’ll admit, the first time I encountered this behavior in iOS 7, I was a bit surprised. I quickly came to not only understand it, but also appreciate it. I’m able to tell at a glance what site I’m on and I can easily get to the URL if I want it. In the meantime, it’s a nice, clean interface that doesn’t disrupt my usage pattern.
The more I thought about it, the more I realized that this move was not only okay for the web, but it is the next logical step in a process that has been ongoing for sometime now.
We don’t own the web
We geeks tend to forget that we don’t own the web. The web is not just for us. We are its caretakers. We groom it and coax it to grow in certain directions. The web is for everyone, that means geeks and non-geeks alike. And whether we like it or not, there are for more non-geeks than there are geeks in the world. The grandparents and parents, the barely computer-literate middle-aged folk, the kids who don’t really know how to speak yet. The web is for all of them.
If you look back at the history of the internet, you’ll see evidence of this from its early days. There was almost always a push for average folks to be online. America Online and Prodigy grew to be successful because they hid all of the ugliness of the internet at that point in time. Gopher and FTP and even email, to some extent, were hard for people to use and understand. Online services that abstracted away the geeky parts flourished.
The web came after that as a way to continue the forward progress. Those online services represented lock-in, and the web was a promise of unfettered access to all of the information available online. It succeeded because it replicated the most consumer-friendly parts of those online services (embedded images, simple click-to-navigate interactions, and so on).
However, the web of the 1990s was still hostile to people who weren’t tech savvy. It was filled with potential hazards at every turn, from sending credit card information in plain text to email phishing. The consumers of the day fell victim far more frequently than we do today for several reasons: the knowledge of what was good and bad, what was useful or useless, was only available and understandable by geeks. Average people were lost.
Goodbye protocols
About ten years ago, I was showing a teenager something online when he asked me a startling question, “Why are you typing ‘http://’?” I told him that this specified the protocol that I was using to retrieve information from the internet.
“No,” he continued, “I mean why are you typing it? The browser just adds it for you when you hit Enter.”
Was it true? I tried it. Yes, he was right. I explained to him that “when I was his age” we had to type the full protocol into the browser or else it wouldn’t work.
“That’s dumb,” he replied.
He was right. It was dumb to type in the protocol when most of the time it was the same. So browsers changed to insert the protocol for you automatically. No one types “http://” anymore because it’s another thing you can easily get wrong and the average person wouldn’t understand what went wrong. What’s a protocol anyway?
These days, browsers have more or less done away with protocols altogether. There are really only two that are of consequence for end-users: “http” and “https”. And when you come down to it, all an end-user really needs to understand is that one is secure and one is not. The best way to show that is through some kind of imagery and/or color change.
Internet Explorer 11 uses green and a lock icon to show when you’re using HTTPS rather than showing the protocol itself. I expect other browsers to follow suit soon.
Goodbye email addresses
Email addresses are fairly simple, and you’d be hard-pressed to come up with a simpler alternative. Yet, how many email addresses do you know by heart these days? I know my mom, my dad, and myself, and that’s only because I set all of them up. I have no idea what email address my friends or colleagues use, even my brother’s email address is a mystery to me. Why is that?
Because email addresses represent routing information, and when I’m writing an email I’m not thinking about routing information, I’m thinking about the person to whom I’m writing. Email clients know this and so they will automatically look up email addresses based on the name you enter.
Gmail, for instance, shows every email address matching a given name. When you’re done typing the name, only the name remains in the To field (unless you have multiple email addresses for the same name, then it shows the email address as well).
The truth is, the actual email address is usually unimportant. All we really need is to be sure the message is going to the correct person. We rely on contacts lists to keep track of email addresses that we need and look them up as necessary. It’s nice that we can easily share that information over the phone with a friend, but then that friend likely adds it to a contact list under the person’s actual name as well.
Aside: goodbye phone numbers
As a brief aside, I liken email addresses to phone numbers. At one point, you absolutely had to memorize phone numbers to have a pleasant experience. It was horrible needing to dig out your personal phone book or, heaven forbid, the white or yellow pages to look up a phone number. So, we all walked around with a bunch of phone numbers in our head to make the process simpler.
With the popularity of mobile phones, however, we have largely contributed to the demise of the phone number. Phone numbers are now things you don’t even need to know – they are stored in your phone and used by telling the phone who you want to call. It’s the same mode of operation as email. Tell the device who you want to contact and it will do you the favor of using the correct routing information.
Some would argue that phone numbers have important information. In the United States, phone numbers are made up of a three-digit area code, followed by a three-digit central office number, followed by a four-digit station number. The area code tells you not only what state the phone number resides in, but also the part of the state. The central office number maps to a city. So in a sense, you have a ton of geographic information encoded into the phone number that makes it possible to figure where callers are located.
Of course, cell phones changed all that. If you grew up in one state and moved to another, you might keep the same cell phone number. Then you have a Florida number while living in Kansas. The information encoded in the number is no longer relevant or useful other than as routing information.
These days, I know four phone numbers by heart: my parents’ number, my home phone, my cell phone, and my mom’s cell phone. Dad’s cell phone loses out, and my brother? Not a clue. And I’m okay with that because I know that I don’t actually need that information in my brain. In fact, most smartphones today don’t show you the phone number being called unless there’s no name associated with it.
And yet, people rarely freak out when they can’t see the phone number of the person they’re talking to. Why? Because this routing information isn’t necessary to the experience.
If you want to share someone’s number, then you might actually look it up and repeat it to someone else. Or you might just share the contact using your phone. Either way, the sharing experience is pretty easy before the phone number resorts to routing information in someone else’s phone.
Goodbye URLs
And so we come back to the humble URL. What most geeks seems to miss is that non-geeks rarely use full URLs outside of sharing. URLs act, essentially, like phone numbers. People don’t need to know that they exist at all in most cases. I learned this by watching my dad use the web one day many years ago. I instructed him to go to boston.com, at which point he opened up his browser (which defaulted to Yahoo as its search engine) and typed “boston.com” into the search box. A light bulb went off in my head: he doesn’t distinguish between domain names, URLs, and search terms. To him they are all the same, just stuff you type into a box to get to see what you want.
These days, dad is a lot more savvy, but he still doesn’t use URLs. Anytime he goes to a site that he wants to remember, he creates a bookmark for it. Then, the next time he wants to view the site, he opens up his bookmarks and clicks the title of the thing he wants. Yes, it would be faster for him to type “boston.com” when he wants to go there, but that’s not the way he thinks about it. He wants to think about the thing to read and not where it’s located. The URL is just routing information to get the information. I encourage you to watch your non-geeky friends or family members use the web for a while.
Remember, most of civilization is made up of non-geeks who just want to find the stuff they want and get on with their lives. They don’t care if they get there by URL, by clicking a link, by search, or by using a bookmark. Whatever is easiest for them will work.
The one spot where URLs get most of their face time is in sharing, and even that continues to change. There are so many ways people share links these days. Facebook doesn’t show the URL in shared snippets. Twitter obscures the URL. News articles have Share and Like buttons everywhere. iOS has a share button that copies the URL to the clipboard without you seeing the URL first. URLs have been on the way out for a while.
Most end-users don’t understand URLs any more than they understand phone numbers. It’s a bunch of characters that refer to something. Why does it have this particular format? Who cares! It means nothing to most of the world.
Conclusion
Is Google trying to eliminate URLs from the web? Of course not. URLs are just as important to the web as phone numbers are to the worldwide telephone system. What they’re trying to do is to relegate URLs to the same level as protocols, phone numbers, and email addresses, which is encoded routing information that most people will rarely use in its raw form. If you really want it, it’s there behind a click. You might even consider that an “advanced” use case targeted at geeks.
I would go so far as to say hiding the URL most of the time is the next logical step in the consumerization of the web. We’ve already started down the path of hiding implementation details from end users, and that’s a good thing because the web is for everyone. You shouldn’t need to understand what a URL is or how it works in order to use it.
Who knows, at some point in the future, we might all look back and laugh at how silly it was to need to know things like email addresses and URLs at all.
References
Improving the URL bar by Jake Archibald (jakearchibald.com).





May 5, 2014
URLs are already dead
Last week, there was a fair bit of furor when Jake Archibald wrote an article1 describing an experimental feature in Chrome that hides all but the domain name of the URL you’re on. The idea is very similar to what already happens in the iOS 7 version of Safari: once navigation is underway, the URL is hidden and only the domain name is visible in the location bar. If you want to get to the full URL, then you either click or set focus back to the location bar (in Chrome, you click the domain name).
I’ll admit, the first time I encountered this behavior in iOS 7, I was a bit surprised. I quickly came to not only understand it, but also appreciate it. I’m able to tell at a glance what site I’m on and I can easily get to the URL if I want it. In the meantime, it’s a nice, clean interface that doesn’t disrupt my usage pattern.
The more I thought about it, the more I realized that this move was not only okay for the web, but it is the next logical step in a process that has been ongoing for sometime now.
We don’t own the web
We geeks tend to forget that we don’t own the web. The web is not just for us. We are its caretakers. We groom it and coax it to grow in certain directions. The web is for everyone, that means geeks and non-geeks alike. And whether we like it or not, there are for more non-geeks than there are geeks in the world. The grandparents and parents, the barely computer-literate middle-aged folk, the kids who don’t really know how to speak yet. The web is for all of them.
If you look back at the history of the internet, you’ll see evidence of this from its early days. There was almost always a push for average folks to be online. America Online and Prodigy grew to be successful because they hid all of the ugliness of the internet at that point in time. Gopher and FTP and even email, to some extent, were hard for people to use and understand. Online services that abstracted away the geeky parts flourished.
The web came after that as a way to continue the forward progress. Those online services represented lock-in, and the web was a promise of unfettered access to all of the information available online. It succeeded because it replicated the most consumer-friendly parts of those online services (embedded images, simple click-to-navigate interactions, and so on).
However, the web of the 1990s was still hostile to people who weren’t tech savvy. It was filled with potential hazards at every turn, from sending credit card information in plain text to email phishing. The consumers of the day fell victim far more frequently than we do today for several reasons: the knowledge of what was good and bad, what was useful or useless, was only available and understandable by geeks. Average people were lost.
Goodbye protocols
About ten years ago, I was showing a teenager something online when he asked me a startling question, “Why are you typing ‘http://’?” I told him that this specified the protocol that I was using to retrieve information from the internet.
“No,” he continued, “I mean why are you typing it? The browser just adds it for you when you hit Enter.”
Was it true? I tried it. Yes, he was right. I explained to him that “when I was his age” we had to type the full protocol into the browser or else it wouldn’t work.
“That’s dumb,” he replied.
He was right. It was dumb to type in the protocol when most of the time it was the same. So browsers changed to insert the protocol for you automatically. No one types “http://” anymore because it’s another thing you can easily get wrong and the average person wouldn’t understand what went wrong. What’s a protocol anyway?
These days, browsers have more or less done away with protocols altogether. There are really only two that are of consequence for end-users: “http” and “https”. And when you come down to it, all an end-user really needs to understand is that one is secure and one is not. The best way to show that is through some kind of imagery and/or color change.
Most browsers now use colors and lock icons to indicate the level of security employed by the domain. For example, Internet Explorer 11 uses green and a lock icon to for extended verification certificates. So what will people notice? The protocol or the visuals?
Goodbye email addresses
Email addresses are fairly simple, and you’d be hard-pressed to come up with a simpler alternative. Yet, how many email addresses do you know by heart these days? I know my mom, my dad, and myself, and that’s only because I set all of them up. I have no idea what email address my friends or colleagues use, even my brother’s email address is a mystery to me. Why is that?
Because email addresses represent routing information, and when I’m writing an email I’m not thinking about routing information, I’m thinking about the person to whom I’m writing. Email clients know this and so they will automatically look up email addresses based on the name you enter.
Gmail, for instance, shows every email address matching a given name. When you’re done typing the name, only the name remains in the To field (unless you have multiple email addresses for the same name, then it shows the email address as well).
The truth is, the actual email address is usually unimportant. All we really need is to be sure the message is going to the correct person. We rely on contacts lists to keep track of email addresses that we need and look them up as necessary. It’s nice that we can easily share that information over the phone with a friend, but then that friend likely adds it to a contact list under the person’s actual name as well.
Aside: goodbye phone numbers
As a brief aside, I liken email addresses to phone numbers. At one point, you absolutely had to memorize phone numbers to have a pleasant experience. It was horrible needing to dig out your personal phone book or, heaven forbid, the white or yellow pages to look up a phone number. So, we all walked around with a bunch of phone numbers in our head to make the process simpler.
With the popularity of mobile phones, however, we have largely contributed to the demise of the phone number. Phone numbers are now things you don’t even need to know – they are stored in your phone and used by telling the phone who you want to call. It’s the same mode of operation as email. Tell the device who you want to contact and it will do you the favor of using the correct routing information.
Some would argue that phone numbers have important information. In the United States, phone numbers are made up of a three-digit area code, followed by a three-digit central office number, followed by a four-digit station number. The area code tells you not only what state the phone number resides in, but also the part of the state. The central office number maps to a city. So in a sense, you have a ton of geographic information encoded into the phone number that makes it possible to figure where callers are located.
Of course, cell phones changed all that. If you grew up in one state and moved to another, you might keep the same cell phone number. Then you have a Florida number while living in Kansas. The information encoded in the number is no longer relevant or useful other than as routing information.
These days, I know four phone numbers by heart: my parents’ number, my home phone, my cell phone, and my mom’s cell phone. Dad’s cell phone loses out, and my brother? Not a clue. And I’m okay with that because I know that I don’t actually need that information in my brain. In fact, most smartphones today don’t show you the phone number being called unless there’s no name associated with it.
And yet, people rarely freak out when they can’t see the phone number of the person they’re talking to. Why? Because this routing information isn’t necessary to the experience.
If you want to share someone’s number, then you might actually look it up and repeat it to someone else. Or you might just share the contact using your phone. Either way, the sharing experience is pretty easy before the phone number resorts to routing information in someone else’s phone.
Goodbye URLs
And so we come back to the humble URL. What most geeks seems to miss is that non-geeks rarely use full URLs outside of sharing. URLs act, essentially, like phone numbers. People don’t need to know that they exist at all in most cases. I learned this by watching my dad use the web one day many years ago. I instructed him to go to boston.com, at which point he opened up his browser (which defaulted to Yahoo as its search engine) and typed “boston.com” into the search box. A light bulb went off in my head: he doesn’t distinguish between domain names, URLs, and search terms. To him they are all the same, just stuff you type into a box to get to see what you want.
These days, dad is a lot more savvy, but he still doesn’t use URLs. Anytime he goes to a site that he wants to remember, he creates a bookmark for it. Then, the next time he wants to view the site, he opens up his bookmarks and clicks the title of the thing he wants. Yes, it would be faster for him to type “boston.com” when he wants to go there, but that’s not the way he thinks about it. He wants to think about the thing to read and not where it’s located. The URL is just routing information to get the information. I encourage you to watch your non-geeky friends or family members use the web for a while.
Remember, most of civilization is made up of non-geeks who just want to find the stuff they want and get on with their lives. They don’t care if they get there by URL, by clicking a link, by search, or by using a bookmark. Whatever is easiest for them will work.
The one spot where URLs get most of their face time is in sharing, and even that continues to change. There are so many ways people share links these days. Facebook doesn’t show the URL in shared snippets. Twitter obscures the URL. News articles have Share and Like buttons everywhere. iOS has a share button that copies the URL to the clipboard without you seeing the URL first. URLs have been on the way out for a while.
Most end-users don’t understand URLs any more than they understand phone numbers. It’s a bunch of characters that refer to something. Why does it have this particular format? Who cares! It means nothing to most of the world.
Conclusion
Is Google trying to eliminate URLs from the web? Of course not. URLs are just as important to the web as phone numbers are to the worldwide telephone system. What they’re trying to do is to relegate URLs to the same level as protocols, phone numbers, and email addresses, which is encoded routing information that most people will rarely use in its raw form. If you really want it, it’s there behind a click. You might even consider that an “advanced” use case targeted at geeks.
I would go so far as to say hiding the URL most of the time is the next logical step in the consumerization of the web. We’ve already started down the path of hiding implementation details from end users, and that’s a good thing because the web is for everyone. You shouldn’t need to understand what a URL is or how it works in order to use it.
Who knows, at some point in the future, we might all look back and laugh at how silly it was to need to know things like email addresses and URLs at all.
References
Improving the URL bar by Jake Archibald (jakearchibald.com).





Nicholas C. Zakas's Blog
- Nicholas C. Zakas's profile
- 106 followers
