What does it mean to be a Software Engineer?
I said in my last blog post that I didn't like the term Software Engineer, which is because of the second word, Engineer, namely that I think it's somewhat inappropriate.
Software around me is insecure, quick hacks are often deployed to side-step problems, many programmers I know refuse to write tests, code grows uncontrollably and isn't refactored, and documentation is always out of date and incomplete.
I've spent a lot of time considering if I can call myself an engineer without feeling like a complete fraud. I've come up with a few things I'm trying to adopt more this year. These things won't stop bad code but does give some comfort knowing that the code I write might be better today than code written yesterday.
Test Driven Development
Much like Dijkstra pointed out that unconstrained GOTO was harmful, we learned to limit ourselves, and many high-level languages such as Go and PHP have restricted GOTO, where it's not possible to jump over allocations, for instance.
If TDD causes some kinds of code to be impossible to write, perhaps that is a good thing, much the same way limiting ourselves to use safe use of GOTO, often through constructs like
while loops, was a good thing.
You can write code without tests, of course. However, it requires a certain amount of discipline to write tests alongside the code. The same way Accountants must have the discipline to do double-entry bookkeeping because it reduces errors.
In as many ways as possible, embrace automation. If you aren't using Continual Integration, check out Travis-CI and other tools. Continual Integration ensures every commit, or every pull request, has passing tests, no syntax errors, and anything else your CI tests check for. If you aren't doing tests automatically, you WILL forget to run tests and WILL check in code that has syntax errors. I speak from experience. If you can't block it at source (e.g. Git pre-commit hook), at-least fail fast and fail hard, so you can fix the problem quickly.
Accept You Are Human
Tools can help you catch your mistakes! Think of them as pair programmer if you have nobody to program with.
One thing I can absolutely say has saved me so much time is to write a Git pre-commit hook that runs your tests. I've lost count how many times a commit has been blocked at work because I changed the code and forgot to run the tests to make sure they aren't. What may help a bit here is Test Contra-variance, but that's something I'm still trying to learn.
You WILL write bad code and these tools can help you with typos, syntax errors, unreachable code, and more. In Go, tools like go vet (linter), go fmt (formatter), and pkg/testing (unit testing) are great. Go vet tries to find problems that won't be caught by the compiler.
In PHP, fantastic tools include PHP Mess Detector (linter), PHP Code Sniffer (formatter), PHP Unit (unit testing), and catching E_ALL via
set_error_handler and re-throwing everything as a fatal error.
Don't ignore warnings and notices, check what linting and testing tools are popular, read other people's code, go to meetups and talk to people there.
Continue to learn the old, great ideas, and continue to research and consider the new ideas.
The best metric I have for this is to look at the code you wrote a year ago. If it looks immediately, and objectively, bad to you, then congratulations -- you've improved in the last year! It may just be a better or more consistent coding style, or maybe you've learned how to write similar code but in a much more efficient way.
The day your old code looks indistinguishable from your recent code is the day you need to panic a little. Reach out to some developers you know and ask them what they've worked on lately. I'm sure there will be something new for you to experiment with.