tl;dr: There are four goals you can prioritize when coding: efficiency, readability, flexibility, and brevity.
In English, we understand that “good writing” means something different between a novel, an airplane repair manual, a poem, and a tweet. But in writing computer code, sometimes we forget that there are similarly different goals that the code may be optimizing for.
In project planning, interviews, and even in personal projects, it’s important to be crystal clear on goals, as compromises are inevitable. Not all code can be efficient, readable, flexible, and brief!
Efficiency has traditionally been the assumed goal of all coding, and remains the primary yardstick for technical interviews. You try to minimize processor cycles, storage space, or network traffic. You analyze with Big O and employ profiling tools to verify. The need for efficiency is driven by the sheer amount of data to be processed (Big Data, training sets, etc) or by limited resources of mobile devices. In extreme cases, this can mean dropping down to assembly code or employing PhD level mathematical tricks.
Resources to be optimized: CPU, memory, network traffic.
Readability is more and more recognized as a worthy goal, even at the expense of efficiency. For example, what good is it if your nightly batch script runs five seconds faster if only a Super-senior Engineer can understand the code? Or if a single mistake could mean that an eight hour training run gets the wrong parameters passed?
Readability also means choosing names and data structures that minimize possibly confusion. Recursive solutions are often elegant, but experienced engineers agree that generally iterative solutions are easier to understand.
The rise of Open Source has brought readability into the spotlight. A project won’t attract new contributors if they can’t understand the code. Likewise, companies have learned that having a readable code is required if you want to attract people to your libraries. For example, the APIs and example programs for Google’s Tensorflow and Facebook’s GraphQL are clearly written.
Resources to be optimized: future developer time (including yourself!), attractiveness to outside developers
Flexibility is an under-appreciated goal in coding. When building a prototype or merely exploring an idea, one doesn’t care so much about efficiency or helping outsiders understand the code. Instead, one builds for uncertainty. For example, you don’t know yet if the project will use Tensorflow or OpenCV for counting the number of cats that walk by, so you create an interface that returns “numCats” and cleanly allow for different git branches to test out possible solutions.
Resource to be optimized: developer time, switching costs
Flexibility is also the primary goal of explorer-style coding, covered in my previous post Lewis and Clark Style Development.
Brevity is the final goal of coding. This is the case when you’re hashing out an algorithm with a co-worker in a Juypyter notebook, or doing a coding interview on a whiteboard. You and your co-worker will implicitly understand that the variable tsr means “total sheep remaining,” or that the first and second elements in each tuple will represent the left and right branches of a binary tree.
In a classic technical whiteboard coding problem brevity becomes important, but the interviewee is presumably also being evaluated on effeciency and readabilty. If you’re being interviewed, it’s best to be very clear what tradeoffs you are making between these.
Resources to be optimized: whiteboard or screen space, handwriting time.
When writing code, one often comes to forks in the road. I’ve found that having clear priorities between efficiency, readability, flexibility, and brevity keep everyone on the same page, especially junior developer who don’t have as much cultural acclimation to intuitively understand different contexts.