If the devs on my team remember anything, I want them to remember these fundamental programming guidelines. 🎩
(examples are based on a Javascript environment, but many can be extrapolated to other environments)
Handle all errors
Don't let anything fail silently! You will thank me when you have to debug some random error on Production that does not occur locally.
On the client-side, you'll want to flash the error to the screen in whatever framework you are using:
this.props.dispatch({ type: 'flash-error', data: "Specific error message." })
On the server-side, you'll want to print to the console and either rethrow or send a 500 response (if you are in a route):
someAsyncThing
.then(...)
.catch(err) {
console.error('Specific description of where we are in the code.', err)
throw new Error(err)
// make sure to send a 500 to the client if in a route!
// res.status(500).send('Specific description of where we are in the code.')
})
Make sure you print the actual err
object as seen above, not just the error message, so that you print the full stack trace! Do NOT do console.log('ERROR: ' + err)
as the error will be converted to a string and the stack trace will be lost!
Prefer immutable
State (mutable values) is the source of all evil. More seriously, it is a messy construct that introduces time as an implicit variable. More simply, it makes your code more error-prone and harder to debug.
- Instead of using
var
orlet
, useconst
. This one will set you on the right path 95% of the time. If you find yourself reaching for something other thanconst
, ask yourself if you really need a mutable value. It's far better to create a brand new value most of the time than reusing an existing value. The reason this is so important is not that you are going to realistically mess upvar
every time. It is that writingvar
forces other developers to search the entire file to make sure the value is not being modified in any other sneaky ways.const
communicates loud and clear: this is guaranteed to be the only place this value is set. This communicates clear intentions and saves other programmers lots of time. - Instead of writing a
for
loop and pushing items onto an array, do anarr.map(...)
. - Instead of writing a bunch of logic to process array items to generate a final value, use
arr.reduce(...)
(you can really do a lot withreduce
). - Instead of modifying a value in an object, use
Object.assign
to copy an object with a new value.
Code bunnies everywhere will rejoice! 🐰
Return promises
If you write a function that does some asynchronous processing, return a promise that resolves when it completes! This is a good practice even if you are not using the return value. Without it, there is no way to catch errors, no way to tell how long something took, and no way to serialize other operations. Always returning a promise for asynchronous functions gives you flexibility in the future to chain asynchronous options together and handle errors consistently.
Respect abstractions
What?!? I know. This one is hard to explain. Probably the most important one to help you level up as a programmer though. Write code that does one thing and does it well. Write functions/modules that hide their implementation, only exposing the minimum interface required. Make decisions about what functions/modules are responsible for, and don't let that bleed into other areas!
Saying the job of a programmer is to "just get it to work" is like saying the job of mountaineer is to put their left leg in front of their right. That's the easy part. The job of a programmer is to manage complexity. (Complexity != Learning Curve!!!) Good code hides implementation details while exposing a clean, intuitive interface to other modules. Much of programming is making judgment calls about possible tradeoffs. Optimize for low complexity and surface area and you will be in good shape 99% of the time.
Invest in your codebase
- Use a linter. How nice to have a machine keep your code tidy! 🤖
- Write unit tests. They will save you hours of work finding regressions. 10% vs 0% coverage is 100x better than 20% vs 10% coverage!
- Take time to build protection around common slip-ups. For example, a simple pre-commit hook that checks for extraneous dependencies in a node project will catch developers who accidentally installed a module without saving it to the package.json:
"echo \"Looking for extraneous dependencies...\" && ! (npm ls --depth 0 2>/dev/null | grep extraneous && echo \"Extraneous dependencies detected. Please use \"npm install --save\" for wanted packages and \"npm prune\" to remove all unwanted packages.\")"
. Yay! - If you realized you implemented something the wrong way, make the effort to fix it even if it's already working. It's one thing to choose a simpler, less robust implementation because of the engineering effort saved. It's another thing to justify keeping shitty code in your code base because "it's not worth it now." Trust me, you do not want to go down this path. It sets up a bad cycle of writing bad code, hiding a deeper problem of poor planning/architectural skills. Those are the raw ingredients of technical debt.
I hope these tips help you and your team level up your skills and maintain a clean and maintainable codebase!
Raine Revere
clarityofheart.com
Very insightful. Thanks for the article. But, how do you motivate members of the team to work on themselves and learn new programming concepts? For example, take courses, go to meetups, etc...
Glad you enjoyed it. Your comment is... well-timed! I am struggling with some of the same things myself. It is relatively easy to enforce code quality policies. It is a lot harder to change someone's attitude towards coding and work. I admit that I am in a somewhat pessimistic phase right now; it seems that some people have a desire to learn and grow, and others just want to do the minimum to get by. Not sure there is much that I can do to change that.
I have seen companies who have adopted rigorous training and development practices. I'm sure they get good results. I'm not sure I'm completely on board ideologically though. It can create an atmosphere of external motivation and performance expectations. This may ensure strong team performance, but I am not sure that it helps people realize their potential in a more holistic way. Interesting topic :).
Yes, indeed a quite intriguing topic. I definitely agree with you regarding the flawed ideology. Companies should push their employees to want to learn because of themselves, not because they need to. But that opens up another topic altogether. Some people simply do not have a desire to grow. They're perfectly content with where they are, and how they got there. The only thing you can do is to be a "community leader" of sorts. I've seen that it is much easier for such individuals to follow along to meetups or workshops if you are the one to instigate and create such events. Looking at your GitHub, I seem to doubt you are new to public speaking at events such as I mentioned above. :)
I'm very glad to have had this talk. Looking forward to reading more from you.
Great info from great person :)
Your github is just hardcore impressive... when look at that I know why I am simply too old for learning coding - lol.