Sunday, August 10, 2014

The best minds of my generation are thinking about how to make people click ads - and that's ok.

"The best minds of my generation are thinking about how to make people click ads. That sucks." - Jeff Hammerbacher
There is a meme going around that too many programmers are wasting their careers working on meaningless software: they spend all their time trying to get people to click on ads, they aren't tackling the important stuff, and they aren't solving the biggest problems of today. It's as if all programmers should drop what they are doing and instead try to cure cancer, end world hunger, and generally save the world.

I'm going to call bullshit.

First of all, don't knock ads--or, to be more accurate, don't not knock making money. The most well intentioned company in the world can't accomplish any of its lofty goals if it has no money, and for many companies, ads are the best way to earn that money.

For example, you are probably one of the billion plus people who search Google over 100 billion times per month (!) to help plan your day, learn new information, and answer questions. It's hard to imagine life without it.
Google also builds maps, videoemailphones, and even more recently, they are trying to provide Internet access for everyone in the world, define what it means to be a healthy human, and to create self-driving cars. And all of this is powered by ads: more than 90% of Google's revenue comes from advertising.

If you kept in touch with your friends and family, read the news, or even followed a link to this blog post, it was probably through Twitter or Facebook. Twitter has played a part in starting revolutions in several countries; so has Facebook. In fact, almost everyone with Internet access has been touched by Facebook (they have 1.32 billion active monthly users) and for those without Internet access, Facebook is trying to help. And just like Google, 90% of Twitter's revenue and nearly 90% of Facebook's revenue comes from ads.

Many talented engineers spent enormous amounts of time at these companies getting you to click on those ads. The result, I'd argue, has been remarkably world changing: three companies, driven primarily by ad clicks, have connected us to information and to each other like never before. It's almost as if Adam Smith was on to something with the whole invisible hand idea.

But this debate isn't really about ads. I'm guessing what people are actually upset about is that so many talented developers are working on products that are not "important". That is, they are building software for their own personal amusement or financial gain instead of working for the benefit of us all.

Well, here's a question: how do we determine which companies or ideas will most benefit the world?

In a remarkable talk called The Importance of Mathematics, Timothy Gowers tackles this same question with regards to mathematics:

Gowers claims that most mathematicians are drawn to intellectually interesting problems rather than practical ones. In fact, he talks about the famous Cambridge mathematician G. H. Hardy, who was "perfectly content, indeed almost proud, that his chosen field, Number Theory, had no applications, either then or in the foreseeable future. For him, the main criterion of mathematical worth was beauty."

Many mathematicians prefer problems that are beautiful to those that are useful. Despite that, mathematics has been the basis for countless discoveries of immense practical value: physicists, chemists, engineers, programmers, and countless others use math on a daily basis to build all the tools and technology of modern society. Even Number Theory, which seems entirely like math for math's sake, turns out to have many practical applications, including RSA encryption, the basis of all Internet security, and the reason you can use passwords, credit card numbers, and exchange other information online securely. Hardy would've been disappointed.
Gower's diagram of math knowledge: there is no way to separate the "useful" and the "useless"
Math is deeply interconnected and unpredictable: there is simply no way to know which parts of it will turn out to be important in the real world and which parts won't. The world of companies and products is similar: there is simply no way to know what companies or ideas will end up being a huge benefit to the world and which ones won't.

For example, it would've been hard to argue an algorithm inspired by citation analysis could change the world so profoundly--even Larry Page was not convinced as, in the late 90's, he offered to sell the company to Excite for just $1.6M (today, Google is worth around $400B). Many people would scoff at the idea of starting a company to share podcasts, but this is actually the origin of Twitter. As many as 50% of all scientific discoveries may happen by accident and many of the most world-changing ones were not the result of an explicit effort to save humanity (examples). Even the porn industry has had a profound impact on technology. You never know what will change the world.

There is an old Soviet joke my dad used to tell:

Stalin asks his staff, "how many movies do we make per year?"
"100 movies, Comrade Stalin."
"And how many of them turn out good?"
"10, Comrade Stalin."
"Alright, next year, only make the 10 good ones."

Of course, this isn't a justification to blindly build dumb crap, JerkTech, or anything actively harmful. This is not an excuse to work on projects you don't care about nor a reason to put up with Dilbert-like jobs. This post is a call for moderation: it would be impractical for everyone to try to work on projects that obviously change the world; it would be misguided to abandon all projects that change the world, but not obviously.

If you've got the passion and the skills to cure cancer or take on world hunger, then by all means, do it. But if you don't--and many people don't--it's perfectly fine to work on something else you're passionate about. If you can build something people want, you have a chance to make the world a better place. Even if it involves ads.

Tuesday, July 15, 2014

The Saga Of The Stank

My hand is over my mouth, my eyes are watering, and I'm trying to hold my breath, but every few seconds, my throat tries to turn itself inside out. Most smells, after a little while, fade into the background -- you become desensitized and can no longer detect them. But not this smell. You remember the sloth scene from Se7en? The one where the cops, handkerchiefs over their mouths, walk into a room that has hundreds of Little Tree car air fresheners hanging from the ceiling and find a guy who has been chained to a bed for a year, living in his own waste while his body rotted away? It was like that. Minus the air fresheners.

A week ago, Molly and I had entered our apartment for the first time after a month and a half of traveling. We had been to the Philippines, Thailand, Boston, and were finally home, after a long flight. It was nearly midnight and all I wanted to do was bury my face in a pillow, cocoon myself in a blanket, and breath in my bed, which smells like sleep. Instead, I found myself breathing in noxious fumes. Which smell like noxious fumes.

Molly's first guess was that we had forgotten to take out the trash, but when we checked, it was empty. I looked for anything rotting in the sink, but it was spotless. Molly cracked open the fridge -- also empty. However, as she closed the refrigerator door, it pushed some air out of the fridge and in our direction. A second later, a wave of warm, putrid shit smelling foulness washed over us.

"Oh dear, we've got to deal with this", I said. Or maybe it was something more along the lines of "Oh Jesus fuck what the shit is that???"

I readied myself and peeled the fridge door open again and peered around. We had eaten or thrown out all the food before leaving on vacation, so the shelves were empty. All that remained were a few crumbs and stains. And yet, a cloud of corruption was flooding out of the fridge -- I swear I could see green stink lines.

"We've got to clean this up", I said. Molly suggests it was more like "Oh come on! Why the... what is the... what the fuck is that goddamn smell???" It was go time.

Approximate re-enactment of me approaching the fridge
Molly and I began pulling out the shelves and drawers and washing them. The fumes of -- what was it? Rotten eggs and a dead skunk floating in a bath of spoiled milk? -- continued to waft through the apartment. We were finally on the last shelf when I randomly decided to peer into the freezer. Although the fridge was empty, we had left the freezer running to preserve frozen goods and various condiments. I peered around and saw a package of ravioli, a bag of Ikea meatballs, a bottle of maple syrup, some pink liquid, and then, wait a second, on the door... Oh god, what the hell was that??

I slammed the freezer door shut.

The creature I thought I had seen on my freezer door
My brain was still processing what I had seen. Unfortunately, shutting the freezer door had pushed out a new cloud of noxious gas that nearly knocked me unconscious. As I came to, I began to wonder: why did the freezer smell worse than the fridge? Why was there an Alien facehugger on my freezer door? But most of all, I couldn't get out of my mind the pink liquid in the freezer.

Wait a minute, why was there liquid in my freezer?

I took a peek at the controls in the fridge:

Pop quiz: what happens if you leave the freezer setting at "4", but turn the refrigerator setting to "off"? Did you say that both the freezer and refrigerator shut off? Because that's exactly what happened. For the entire time we were traveling. That's 1.5 months.

For six weeks, some monstrosity had been stewing, growing, incubating in my freezer. We had been scrubbing the refrigerator shelves, but all this time, the real evil lay quietly above. But what was it? What fiend lay in waiting?

I had to know. But I didn't want to know. Molly and I stared at each other. Our imaginations danced. Within the freezer, there lurked unknown dangers, and I felt naked. Actually, I was mostly naked, because I had stripped down after noticing that the putrid smell was getting in my clothes. I searched the house for some protection and found... a single glove. Not zero, not two, but one glove. Seriously, I don't understand why you would have just a single rubber glove, but there you have it. It was purple.

I also found a bottle of Lysol, but it was almost empty. So there I was, wearing a pair of boxers and a single rubber glove, holding a bottle of Lysol, heading into the den of a dragon that could peel the armor off an Abrams tank with a single breath.

I closed my eyes and pulled at the freezer door. As it swung open, I caught sight of a pint of Ben and Jerry's ice cream that had transformed into a Xenomorph egg. No, that's not right. The ice cream had spawned a huge blob of mold that tore through the lid and crawled, stretched, and oozed its fuzzy blue green body up the freezer door. I brought the lysol up, took aim... but I was too late. As the door swung a bit further, the full power of the smell hit me.

Later, when I told this story to my sister, she asked why I didn't take a picture of the mold. The answer is that this was not mold. This was biological warfare, a weapon of mass destruction, the poison gas from the Hunger Games that causes your skin to burst into boils on contact. As the toxic cloud washed over me, it was as if millions of voices suddenly cried out in terror... and then farted. A smell so foul that we gave it a name: it became known as The Stank. This was no time for selfies.

My senses returned to me and I went to war. With one hand, I shoveled all the food left in the freezer into the trash. With the other, I began spraying with lysol. And I kept spraying. And spraying. And spraying. And spraying some more.

A reenactment of our battle against The Stank.
Finally, the bottle was empty. Now, the hard part. I had to wipe it all down. That meant reaching my hand - the one gloved hand - into The Stank. This had all the appeal of reaching straight into Satan's asshole.

I don't really remember what happened next. Somehow, hours later, I was huddled in corner of the shower, knees pressed to my chest. No amount of soap could wash out The Stank.

But our battle was not finished. The next day, the freezer still smelled horrible. We washed everything with soap and water. Then we tried baking soda and water. Then vinegar and water. Then we realized it isn't a great idea to mix baking soda and vinegar, unless, of course, you're trying to create a volcano for your 4th grade science fair.

The next day, the smell was still there. We went out and bought an anti-mold spray that contained bleach. We filled the fridge and freezer with the stuff and let the chlorine gas waft through it. It didn't help.

Then we filled the fridge with smell absorbers: baking soda, charcoal, coffee grinds, oatmeal. We packed plates, bowls, and cookie trays full of the stuff and arranged it in the fridge. It looked like an altar of offerings to a vengeful god. It was our tribute to The Stank. It was not enough.

Worse yet, The Stank followed us. A smell that powerful doesn't just go away when you leave the house. You begin to imagine The Stank everywhere you go. The funky cheese at the fancy restaurant reminds you of The Stank; the bathroom at the library smells of Stank; does that guy on the treadmill have terrible body odor or is that The Stank too? Wait, do I smell like The Stank? Have I become The Stank?

We spent a full week trying every remedy imaginable. We took out shelves, we unscrewed panels, we scrubbed, wiped, sprayed, brushed, and polished every surface. Every visible inch of the fridge became a shiny, unnatural white. But despite it all, The Stank remained.

Finally, today, we ordered a new fridge. The Stank won.

So, kids, here's the moral of the story:
  1. Fuck the environment. We tried to be green -- to save a little energy by shutting off the fridge during our trip. In return, we got The Stank. In fact, once you factor in all the chemical cleaning products, the rolls of paper towels, the years of our lives lost breathing in spores and cleaning agents, and the need to buy and ship a new fridge, I'm not entirely convinced our conservation efforts paid off.
  2. Fuck bad design. If your fridge has separate control knobs for the fridge and freezer, perhaps they should really be separate? Learn design, learn the principle of least surprise, and don't make me think.

Thursday, May 29, 2014

Must-See Tech Talks for Every Programmer

I love a good tech talk. I like to watch them, I like to give them, and now that I have lots of free time on my hands, I've put together a list of the must-see talks for every programmer. In this list, I've avoided language or library specific talks and instead focused on high-level, general topics that apply to everyone:
  1. The future of technology
  2. User interface
  3. Programming language design
  4. Software engineering
  5. Computers and learning
  6. A career in programming
  7. Computer gaming
  8. Fun talks
If I missed a talk you love, leave a comment. Happy watching!

When thinking about the future, you can't do better than Alan Kay. In The Future Doesn't Have To Be Incremental, Kay describes how Xerox PARC was able to develop so many new technologies in such a short time, including the personal computer, bitmap displays, GUI, desktop publishing, word processing, laser printing, Ethernet, and object oriented programming. The key was a culture focused on invention - that is, fundamentally new research - instead of incremental innovation. Invention requires a significantly higher investment of money, much longer time frames, and a different approach to problem solving ("wouldn't it be ridiculous if in 30 years we didn't have...").

Other essential talks on the future of technology:
  • The Mother of All Demos by Douglas Engelbart. A demonstration of hypertext, graphics, video conferencing, the mouse, word processing, and much more - all in 1968! This is the kind of leap frog invention Kay is referring to.
  • The Future of Programming by Bret Victor. A brilliant talk where Bret Victor takes us back in time and reminds us that "the most dangerous thought that you can have as a creative person is to think that you know what you're doing. Because once you think you know what you're doing you stop looking around for other ways of doing things and you stop being able to see other ways of doing things. You become blind."
  • The Computer Revolution Hasn't Happened Yet by Alan Kay. "I made up the term object-oriented and I can tell you I didn't have C++ in mind."

Inventing on Principle by Bret Victor

Bret Victor's talk Inventing on Principle will make all of your programming languages and tools feel obsolete. He presents a new way to write code: a user interface that makes the computer do the tedious work so that you can experiment with and react to your code instead of trying to simulate it in your head. This not only makes it much easier to learn programming, it fundamentally changes how we go about solving problems.

More UI goodness:

Simple Made Easy by Rich Hickey

Rich Hickey, the creator of Clojure, has the ability to make you see basic concepts in computer science in a whole new light. Complexity is one of these basic concepts and Simple Made Easy defines some of the best tools - the best language - to reason about it.

A few other talks to add to your playlist:
  • Are We There Yet? by Rich Hickey. Another foundational talk by Hickey that will force you to reconsider state, time, identity, values, and types.
  • Growing a Language by Guy Steele. One of the most clever presentations I've ever seen on programming language design. Give it about 10 minutes - the payoff is amazing.
  • The Science of Insecurity by Meredith Patterson. Why current systems and protocols are inherently insecure and how to fix that in the future.

Greg Wilson will force you to look closely at how you make decisions in software engineering: should you use Java? Ruby? Play Framework? Rails? TDD? Agile? Code reviews? Most of your answers are probably based solely on opinions, memes, trends, and anecdotes. What We Actually Know About Software Development, and Why We Believe It's True is an important call to change our practices and move to a world of evidence-based software engineering.

Other great talks:
  • Real Software Engineering by Glenn Vanderburg. Software engineering as it's taught in universities simply doesn't work. It doesn't produce software systems of high quality, and it doesn't produce them for low cost. Sometimes, even when practiced rigorously, it doesn't produce systems at all.
  • Hammock Driven Development by Rich Hickey. "Most of the biggest problems in software are problems of misconception." To solve hard problems, step away from the computer, take some time to think, and write it down.
  • The Language of the System by Rich Hickey. We focus extensively on the perfect programming language to build a single system, but what about languages for how multiple systems communicate with each other?

Daphne Koller and Andrew Ng are trying to reinvent education. They created Coursera, which offers real university classes, online and for free, to anyone in the world. What we're learning from online education talks about some of the techniques they are using to run classes of hundreds of thousands of students - including video, discussion forums, interactive UI's, automatic grading, and peer grading - and how this experiment is giving us unprecedented insight into how humans learn.

A few other powerful talks on education:

You and Your Research by Richard Hamming

You and Your Research is the blueprint for a successful career in any discipline, not just research; in fact, the talk has the nickname "You and Your Career". In this lecture, Richard Hamming shares his observations on "why do so few scientists make significant contributions and so many are forgotten in the long run?'' Some of the key ideas include courage, luck, drive ("knowledge and productivity are like compound interest"), a focus on important problems ("If you do not work on an important problem, it’s unlikely you’ll do important work"), open doors, selling the work ("I suggest that when you open a journal, as you turn the pages, you ask why you read some articles and not others"), and much more. This should be required viewing for every high school student.

More talks on how to succeed in the programming industry:
  • The Myth of the Genius Programmer by Brian Fitzpatrick and Ben Collins-Sussman. This talk isn't about geniuses or 10x programmers, but rather, about building a culture that avoids elitism and provides support for personal growth, collaboration, and ideas.
  • Programming Well With Others: Social Skills for Geeks by Brian Fitzpatrick and Ben Collins-Sussman. The Fitz and Ben duo are back to remind you that you need to learn more than just programming languages, compilers, debuggers, and algorithms to be a successful software engineer
  • JavaScript Masterclass by Angelina Fabbro. Don't let the title fool you: this talk is a tutorial for how intermediate developers can become experts in any topic, not just JavaScript.

By the time kids graduate high school, they have spent 10,000 hours playing games: this is roughly equivalent to the time they spend in school (if they had perfect attendance!) and the amount of time it takes to become an expert. What are they learning during those 10,000 hours? Jane McGonigal will show you how this time and learning can be used to make a better world.

More gaming goodness:
  • The game that can give you 10 extra years of life by Jane McGonigal. A powerful talk by McGonigal about how games can improve our lives and how they helped her recover from suicidal depression following a severe concussion.
  • Human Computation by Luis von Ahn. We can use human brain power and gaming to solve problems that are difficult for computers, such as image recognition, translation, and "common sense".
  • Design Outside the Box by Jesse Schell. What happens when games invade every aspect of our lives.

Wat by Gary Bernhardt

Now, it's time for some fun. Gary Bernhardt's talk Wat is 5 minutes of pure awesome.

A few others to brighten your day:

Monday, May 19, 2014

Don't learn to code. Learn to think.

This blog post was covered on Lifehacker and translated into Spanish and Chinese. 

It seems like everyone is trying to learn to code: has celebrities like Bill Gates, Mark Zuckerberg, and Chris Bosh telling you anyone can code; CoderDojo's are springing up all over the country; the UK has made it part of their official curriculum for all grade school kids.

I think this is slightly misguided. Don't get me wrong - I do think the world would be better off if everyone had some familiarity with coding - but coding itself should not be the goal. Computers and programming are just tools. They are a means to an end.

The real goal should be to teach people a new way to think. In other words, we should be trying to teach computer science and not just coding. In this blog post, I'll explain the difference between the two, and why focusing on the right one is critical for the movement to succeed.

If you prefer a video explanation, I highly recommend Simon Peyton Jones' wonderful TED talk Teaching Creative Computer Science, which was the inspiration for this post:

Still here for the written version? Great. Let's get started by asking a key question: why should you care about coding or computer science at all?

To answer that, we'll take a walk.

Welcome to the real world
You're probably reading this blog post in Chrome or Firefox, running on Windows or OS X, on a laptop or desktop. I'm guessing you also spent some time today reading email, checking your friends' Facebook statuses, or watching a video on Youtube. Much of your life is on computers these days: your medical records are in a database; you resume is on LinkedIn; you use Google and Facebook to market your products; you use Amazon to buy them; you file your taxes online; you manage your bank account on a website; perhaps you even dabble in digital currencies.

Now, look up from your computer: in your pocket, purse, or on a desk nearby, you may have a smartphone. It's loaded with a GPS, camera, touch screen, and tons of apps. If you're in your living room, you might also have an LCD TV hooked up to digital cable, a DVR, DVD player, Apple TV, XBox, or PlayStation. The movies, music, and games you may play on those devices are packed full of computer graphics and digital audio processing.

Let's head outside. Did you walk past your car? Modern cars are designed using software, built in a factory full of robots, and stuffed full of computers. If you drive your car, you might use Google Maps to find your way around, Yelp to find a place to eat, or TripAdvisor to find a place to stay. Now, look up: somewhere above you, a plane will pass by that is controlled by auto pilot, has in-flight Wifi and entertainment systems, and is constantly communicating with other planes, traffic controllers, and its manufacturer. Somewhere above that, satellites and space stations are orbiting the earth, taking pictures, measuring the weather, and routing phone calls.

Software is eating the world. But this is only the beginning. Before you know it, you'll be wearing technology, locking your doors with computers, using robots to deliver goods and clean your house, building your own electronics, running your own manufacturing plant, living in virtual reality, traveling in self driving cars, and flying to space.

The matrix is everywhere
Absolutely all of the technology I just described is powered by software. In every aspect of your life, you are surrounded by code. And the amount of code is only going to increase in the future.

Now, just because a technology is ubiquitous doesn't mean you have to study it in school. For example, we all fly in airplanes, but getting your pilot's license is not part of the K-12 curriculum.

However, the tools you need to understand how to think about flying are part of the curriculum:
  1. Physics and math help you understand gravity, forces, pressure, velocity, friction, and lift.
  2. Biology teaches you what happens to the human body at high altitudes, with limited oxygen, and extreme cold.
  3. History explains how the airplane was developed, how it evolved, and its role in travel, commerce, and warfare.
By the time you graduate high school, you have an idea of what a plane is, how it works, and how to use it safely. General purpose classes like physics, math, biology, and history teach you how to think about a wide variety of topics, including airplanes; this is in contrast to a class that teaches you how to use a tool, such as how to fly one specific type of airplane.

For the same reason, we should focus on teaching computer science and not just coding: the former is a general purpose way of thinking, whereas the latter is a specific tool. Let's look closer at computer science to get a better understanding of the distinction.

What is computer science?
Computer science is the study of computation: that is, how to represent and process information. Here are just a few of the concepts you might study:
  1. Problem solving: you'll learn algorithms - that is, general strategies, such as divide and conquer, recursion, heuristics, greedy search, and randomized algorithms - that help you model, decompose, and solve any kind of problem.
  2. Logic: you will start to use precise and formal methods of thinking, including abstraction, boolean logic, number theory, and set theory, so you can solve problems in an air tight manner.
  3. Data: you will touch information theory and start asking questions like what is information? How do you represent it? How do you model the real world?
  4. Systems: how do you design and build complex systems that satisfy a set of requirements and constraints? Systems engineering is an essential topic in almost every business.
  5. Thinking: one of the best ways to understand the human mind is to try to replicate it. Topics like artificial intelligence, machine learning, computer vision, and natural language processing are at the forefront of not only computer science, but also biology, psychology, philosophy, and mathematics.
Note that the above list doesn't really mention coding or programming, because they are just tools that can perform computation: they are not, in and of themselves, computer science.
Computer science is no more about computers than astronomy is about telescopes, biology about microscopes, or chemistry about beakers and test tubes. Science is not about tools. - Michael Fellows and Ian Parberry
It turns out there is another tool that we rely on for computation even more: the brain! The goal of computer science is to teach your brain new, general purpose, and widely applicable ways to think. As technology becomes more and more ubiquitous, this new way of thinking will become just as important as physics, math, biology, and history.

All that said, thinking alone is not enough: we need to know how to apply it. In physics, you do experiments with scales, prisms, and magnets; in biology, you might use test tubes, plants, and petri dishes; in computer science, you learn programming.

What is programming?
Programming, or writing code, is how you instruct a computer to perform some operation. If you've never written code before, you're probably used to interacting with a computer by clicking on things in an existing app. Under the hood, this app consists of code that tells the computer how to display the application, where to store or retrieve data, and how to react to your clicks.

All of programming is based on the principles of computer science we discussed above. It is remarkable that the same set of concepts - logic, algorithms, data, systems engineering - can be used to build everything from the web browser you're using to read this post to the autopilot software on an airplane. Although programming involves lots of math and structure, it is also a remarkably creative exercise: you think products into existence, one line of code at a time.

Learning programming as part of a computer science education brings about a number of benefits:
  1. DIY: if you can code, you can build things for yourself. You can start simple: create a script to rename a bunch of travel photos or an Excel formula to help calculate your taxes. Then, get fancier: create a website for your portfolio; create a mobile app for your company; build a game to play with your friends.
  2. Troubleshooting: once you've built a few apps yourself, figuring out other apps is easier. Once you stop fearing the computer - the unknown - you will become a master of tech support. As technology touches every part of your life, knowing how to navigate it will become as important as knowing how to read.
  3. Career: the goal of learning computer science is not to become a professional programmer. We all study math, physics, and chemistry in school, but we don't all become professional mathematicians, physicists, and chemists. However, if you do have a passion for it, you'll find that software engineering is one of the highest rated, highest paid, and fastest growing jobs out there.
Putting it all together
Let's recap:
  1. Computer science is a new way of thinking. The concepts in it are useful for every single person in a technology-filled world.
  2. Programming is an essential part of learning computer science by applying the new way of thinking. However, by itself, programming is not nearly as general purpose.
Confusing these two concepts is causing problems for the learn-to-code movement. Slate published an article called Maybe Not Everybody Should Learn to Code; the Atlantic wrote Should Journalism Schools Require Reporters to 'Learn Code'? No; Jeff Atwood wrote Please Don't Learn To Code, where he asks a question that neatly summarizes the confusion:
"How [would] Michael Bloomberg be better at his day to day job of leading the largest city in the USA if he woke up one morning as a crack Java coder?"
This is, of course, the wrong question. It is the result of public campaigns that suggest that learning to code, as opposed to learning to think, is the end goal. If even Jeff Atwood, an experienced and respected programmer, is fooled by this distinction, then the average person has no chance of getting it right. The question we should be asking is:
Would Bloomberg - or anyone else - be better at their job if they improved their ability to think by learning new problem solving strategies and developing a better grasp of logic?
I think the answer here is obvious. As the world fills up with more and more technology, I think the answer becomes even more obvious. This is why we need to focus on teaching computer science and not just coding.

How to get started
The good news is that you don't need to wait for to get this message - you can start learning computer science right now! In fact, it's one of the easiest topics to learn, as all you need is a computer and an Internet connection, and if you're reading this post, you probably have both.

Here are some great resources to get you going:

University courses
  1. Coursera
  2. Udacity
  3. MIT OpenCourseWare
  4. Stanford Engineering Everywhere
  5. Academic Earth
Online tutorials
Communities and clubs
  1. CoderDojo
  2. Girls Who Code
  3. Girl Develop It
  5. Coding meetup Groups

Monday, May 5, 2014

You are what you document

Hey, grab a seat - we need to talk about documentation. Now, I know what you're thinking: documentation is tedious, a chore, an afterthought, a redundant source of information given your beautiful, self-documenting code. It's just like a good diet and exercise - you'll do it when you have the time!

Well, this blog post is an intervention. You're hurting others and you're hurting yourself. You poured countless hours into a project, but your co-workers won't use it. You tried to run it in production, but the OPs team won't support it. You put the project on Github, but the fools on Hacker News just don't see the brilliance of what you've done.

The number one cause of startup failure is not the product, but the distribution: it doesn't matter how good the product is if no one uses it. With software, the documentation is the distribution: it doesn't matter how good the code is if no one uses it. If it isn't documented, it doesn't exist.

Think of this blog post as documentation for your documentation. By "documentation", I don't just mean a written manual, but all the pieces that go into making your software learnable: the coding practices, tutorials, white papers, marketing, the community, and the user experience.

I'll be discussing three types of documentation:
  1. Written documentation: READMEs, tutorials, reference guides, white papers.
  2. Code documentation: API docs, comments, example code, the type system.
  3. Community documentation: blog posts, Q&A sites, talks, meetup groups.
Each type of documentation solves a different problem, so most projects should include some mix of all three types. I've tried to include links to open source projects that best demonstrate each of the different types of documentation. If you know of other great examples or other types of documentation that I've missed, please leave a comment.

1. Written documentation

Let's start with what people typically think of when they hear the word "documentation": READMEs, tutorials, reference guides, etc.

1a. The README

Every project should have a README: it is the single most important document in your codebase. The README is typically your first contact with a new user, so your goal is to introduce them to the project as quickly as possible, convince them why it's worth learning more, and give them pointers on how to get started and where to get more info.

A typical README should have the following information:
  1. Description: short "sales pitch". Tell the reader why they should keep reading.
  2. Quick examples: short code snippets or screenshots to support the description.
  3. Quick start: how to get going, install instructions, and more examples.
  4. Further documentation: links to the full docs and more info.
  5. Project organization: who are the authors, how to contribute, how to file bugs.
  6. Legal notices: license, copyright, and any other legal details.
Here are some examples of great README's:
  1. Twitter Bootstrap
  2. guard
  3. Ace
  4. jekyll
  5. hogan.js
  6. ember.js
I usually practice Readme Driven Development, writing the README before writing any code. This forces me to be clear on exactly what I'm trying to build, helps me prioritize the work (anything in the "sales pitch" is a must-have), and provides a great sanity check on what the basic user experience looks like (the quick example and quick start sections are essential). See the original Readme Driven Development post and The Most Important Code Isn't Code for more info.

1b. Tutorials, walkthroughs, and guides

The README gets the user in the door; the tutorial shows them how to walk around. The goal is to guide a new user through example use cases that highlight the idiomatic patterns, the best practices, and the unique features of the project. Use the tutorial to have a dialogue with the user, walking them through the typical development flow step by step and introducing the key ideas. You don't have to cover every single topic and you don't have to go too in-depth: instead, at each step of the tutorial, provide links to where the user can find more info.

For small, simple projects, you may be able to squeeze a tutorial into the README itself, but most projects will want to use a wiki, a blog post, a standalone webpage, slide deck, or even a recorded video. Here are some great examples:
  1. Ruby on Rails Guides
  2. Django Tutorial
  3. Dropwizard Getting Started
  4. Intro to Play Framework for Java
  5. Twilio quick start tutorials
The gold standard, however, is the interactive tutorial. Most developers learn best by doing, so a step-by-step guide that lets the developer participate is the ultimate learning tool. Here are a few great examples:
  1. A Tour of Go
  2. Scala Tutorials
  3. Typesafe Activator
  4. Try Redis and Redis commands
  5. Try Git
  6. Codecademy
Creating your own interactive tutorial is not easy, but it dramatically lowers the bar for trying and learning about your project. Here are some (language/framework specific) tools you may find helpful:, IPython Notebook, java-repl, Pamflet, Typesafe Activator,, Ace Editor, CodeMirror, Cloud9 IDE, jsfiddle, Codecademy, and codepen.    

1c. Reference documentation

Ok, your new user got their foot in the door with the README and they took a few steps by following the tutorial; now, the user actually knows enough to start asking questions. This is where the reference documentation comes into play: the goal is to give users a way to find the specific information they need. In this part of the documentation, you can cover all the major topics in depth, but make sure to organize the information in a way that is easy to search and navigate.

Here are some great examples of reference documentation:
  1. Stripe docs
  2. Django documentation
  3. Dropwizard user manual
  4. Codahale metrics
  5. SQLite documents
For large projects, the amount of reference documentation can be pretty large. How do you keep it up to date? One technique is to include references to real code: that is, instead of typing code snippets directly into your docs, build a system to dynamically include them from a real repository.

For example, consider this entry in the Play Framework async docs:

This documentation is generated from markdown files using the play-doc project. For example, here is the Markdown for the "Returning futures" section:

Notice that the code snippet is not in the Markdown. Instead, there is just the line @[async-result](code/ScalaAsync.scala), which is a reference to ScalaAsync.scala in Play's git repo, where the relevant code is demarcated using special comments:

Since this file is compiled and tested, developers have to update it whenever they make changes to the framework - otherwise, the build fails. Moreover, as the comments identify the section of code as "used in the documentation", there is a good chance the developers will remember to update the relevant part of the documentation as well.
1d. Project websites

Standalone project websites are a great example of documentation as marketing: you can give your project its own home, with a custom look and feel, and content that is linkable, tweetable, and indexable.

Here are a few great examples:
  1. Bootstrap
  2. jekyll
  3. Yeoman
  4. Ember
  5. Foundation
The easiest way to create a website for your project is with Github Pages: create a repo on Github, put a few static HTML files in it (possibly using jekyll), git push, and you have your own landing page on the domain.

1e. White papers and books

If you want to make a project look legit, a white paper, and especially a book, is the way to go. White papers are a great way to explain the background for the project: why it was built, the requirements, the approach, and the results. Books, of course, can contain the material in all the sections above: a quick intro, a tutorial, a reference guide, and more. Books are a sign that your project has "made it": there is enough interest in it that a publisher is willing to put money into printing the book and programmers are willing to put money into buying the book.

Some great examples:
  1. Bitcoin: a peer-to-peer electronic cash system
  2. Ethereum white paper
  3. Kafka: a distributed messaging system for log processing
  4. C Programming Language
  5. Effective Java

2. Code documentation

We now understand the role of written documentation: the README gets your foot in the door; the tutorial shows you how to walk around; the reference guide is a map. But to truly understand how a piece of software works, you have to learn to read the source. As the author of a project, it is your job to make the code as easy to understand as possible: programs must be written for people to read, and only incidentally for machines to execute.

However, the code cannot be the only documentation for a project. You can no more learn how to use a complicated piece of software by reading the source than you can learn to drive a car by taking apart the engine.

As we'll discuss below, code structure, comments, API docs, design patterns, and test cases all contain critical information for learning how to use a project, but remember that they are not a replacement for written documentation.

2a. Naming, design patterns, and the type system

There is no such thing as "self documenting" code, but there are ways to make the code easier or harder to understand. One of the first aspects of code readability is naming: every piece of software defines its own mini language or DSL that consists of class names, package names, method names, and variable names. When a developer uses your code, they are really learning a new language, so choose the words in it wisely! However, since naming is one of the two hardest problems in computer science, I recommend getting yourself a copy of Code Complete, which dedicates quite a few pages to this topic:

Design patterns are another tool for communicating the intent of your code. You have to be careful not to overuse them (see Rethinking Design Patterns), but having a shared vocabulary of terms like singleton, factory, decorator, and iterator can be useful in setting expectations and making the naming problem a little easier. The classic book in on this topic is Design Patterns: Elements of Reusable Object-Oriented Software, aka "The Gang of Four":

Finally, the type system in statically typed languages can be another powerful source of information. A type system can reduce not only the number of tests you write (by catching a certain class of errors automatically), but also the amount of documentation you have to write. For example, when calling a function in a dynamically typed language, there is no way to know the types of parameters to pass in unless the author of the function manually documented it; in a statically typed language, the types are known automatically, especially with a good IDE.

Of course, not all type systems are equal, and you have to use them correctly (e.g. avoid stringly typed programming) to see the benefits. For examples of powerful type systems, check out (in increasing order of power and crazy) Scala, Haskell, and Idris.

2b. API docs and literate programming

API docs are documentation for each class, function, and variable in your code. They are a fine-grained form of documentation that lets you learn about the inputs and outputs of each function, the preconditions and postconditions, and, perhaps most importantly, why a certain piece of code exists and behaves the way it does.

Many programming languages have tools to generate API docs. For example, Java comes with JavaDoc, which lets you add specially formatted comments to the code:

You can then run a command line utility that generates a webpage for each class with the JavaDoc comment formatted as HTML:

Good IDEs can show API docs automatically for any part of the code:

Some frameworks have special handling for API docs as well. For example, automatically extracts the documentation from your REST service and exposes it in a web UI. You can use this UI to browse all the RESTful services available, see what resources they expose, what methods and parameters they support, and even make REST calls straight from your browser:

Here are a few nice examples of API docs:
  1. Java API docs
  2. Scala API docs
  3. Stripe API docs
  4. Twilio API docs
  5. Github API docs
  6. API docs
Literate programming goes even further: the idea is that program logic should be described first in natural language; the code comes second, interspersed amongst the English description where convenient. Instead of organizing programs in a way that's easy for compilers to process (ie, rigid file, folder, and package structure), literate programs should be organized in a way that makes it easier for humans to understand, such as an essay format.

I think literate programming is a great concept, but I'm not aware of any mainstream languages that support it fully. The closest I've seen are projects that use tools like docco, which lets you generate an HTML page that shows your comments intermingled with the code, and feels like a halfway point between API docs and literate programming. Here's an example from Literate CoffeeScript:

There are flavors of docco tailored for specific languages, such as rocco (Ruby), Pycco (Python), Gocco (Go), and shocco (POSIX shell). There is also an extension of docco called Groc, which adds support for a searchable table of contents, handles hierarchies of files and folders, and integrates with Github Pages..
2c. Comments

When used correctly, comments are another important source of information: whereas the code tells you how, comments tell you why. The trick is finding the right balance. Code without any comments can't explain why the program is being written, the rationale for choosing this or that method, or the reasons certain alternative approaches were taken; code with too many comments can often be a sign that the code itself is unclear and instead of fixing the code, the comments are being used as a crutch.

In short: always use comments in moderation and always to explain why.

For the "best" examples of comments, I point you to a hilarious StackOverflow thread: What is the best comment in source code you have ever encountered?

2d. Example code and test code

No matter how good your docs are, you can't force developers to RTFM. Some developers prefer to learn by example - which is a polite way of saying that they like to copy and paste.

Getting the example code right is critical to the success of a project, as many developers will blindly copy and paste it. Your goal is to make as many clean, idiomatic examples available as possible. You may also want to invest extra time with the first few teams that adopt your project to help them write clean code: their projects may become the models for everyone else, so make sure it's a model that's worth following!

Here are some projects with great example code:
  1. Twilio HowTo's and Example Code
  2. Twitter bootstrap examples
  3. Typesafe Activator templates
  4. async.js
  5. Firebase examples
Automated tests are a special case of example code. Tests can be useful as documentation in that they show the expected behavior of the code for a variety of use cases. BDD style unit tests, such as Specs2 and RSpec, even encourage writing test cases as a formal specifications. However, in practice, test code can get tangled up with mock objects, test frameworks, and corner cases, all of which can be a source of confusion if you try to rely on it too heavily as a form of documentation.

Projects with great test code:
  1. SQLite
  2. Apache Lucene
  3. backbone.js
  4. Chromium
  5. jQuery

3. Community documentation

We've talked about written documentation and code documentation; the final piece of the puzzle comes from the people involved with the project and the tools they use.

3a. Project management tools

Most teams use bug tracking software (e.g. JIRA, bugzilla, github issues) and/or project management software (e.g. Basecamp, Asana, Trello). These systems contain a lot of information about the project: what you worked on before, what you're working on now, what you'll work on in the future, bugs found, bugs fixed, and so on.

A few examples:
  1. Play Framework Github Issues
  2. Mozilla Bugzilla
  3. Firefox Roadmap Wiki
  4. Chromium Issues
It's hard to imagine how a TPS report can be useful as documentation, but very often, the discussions over a tricky bug or the requirements gathering before starting a new project contain critical information not available anywhere else. It's not uncommon to come across a bug report or an old wiki page while searching for information about a project, especially if it's an open source project that makes all of this information publicly available.

3b. Mailing lists and Q&A boards

Discussions from Q&A sites like StackOverflow and mailing lists like google groups also come up frequently in search results. Even the best documentation will not be able to answer everything, so cultivating community websites can be a critical part of making software learnable. Over time, these may become some of the most important parts of your project's documentation, as they inherently deal with issues where many developers got stuck.

A few examples:
  1. Play Framework Google Group
  2. Android StackOverflow Tag
  3. Ruby on Rails StackOverflow Tag
This is one area where open source projects shine: being able to instantly find answers by using google is a huge win. That said, for internal/proprietary projects, I encourage you to setup internal mailing lists, maintain an FAQ, and/or install an internal StackOverflow-style Q&A site within your company.

3c. Blog posts, talks, meetup groups

For popular open source projects, some of the best documentation comes in the form of content contributed by the community. For example, blog posts and talks from end users are a valuable source of information, revealing what's really working and what isn't; they are also great marketing, as it makes it clear other people are using project. Even blog posts that completely trash the project can be useful - think of it as a free design review!

If your project is open source, growing a community around it can have a huge pay off. A small investment in "marketing" your project - via good documentation, custom project pages, giving talks, and setting up meetup groups - can yield huge returns in the form of free labor, cleaner code, and better branding.

There are countless great blog posts and talks, so here are a few unbiased, randomly selected links that you should definitely check out:
  1. The Ultimate Guide to Getting Started with the Play Framework
  2. Composable and Streamable Play Apps
  3. The Play Framework at LinkedIn
  4. Play Framework: Async I/O with Java and Scala
  5. Bitcoin by Analogy

Further reading

If you've made it this far, you should now know how, and why, to document your code. I hope you join me in building software that is easier to use and learn.

If you're hungry for more info, I recommend the following resources:

  1. Writing Great Documentation
  2. The Most Important Code Isn't Code
  3. Teach, Don't Tell
  4. Designing Great API Docs
  5. No docs == no product
  6. Pointers to useful, well-written, and otherwise beautiful documentation
  7. If It Isn't Documented, It Doesn't Exist
  8. A beginners guide to writing documentation
  9. Tips for Writing Good Documentation