I’ll never forget the day my manager responded to my suggestion for more unit testing, “So you want to spend time writing non-revenue code”. Only then did I begin to realize the corporate world was changing. My ideas about focus on quality, creating happy repeat customers, valuing and helping employees succeed and be happy, were consigned to the ash-heaps of history.
In my early professional development two books were required reading: In Search of Excellence by Tom Peters and Robert H. Waterman Jr., and Built to Last by Collins and Porras. Over the next decade, emphasis on the concepts contained in those books faded. A lot of corporate training disappeared with the company saying “training is the employee’s responsibility”. Problem is, when a company works on cutting edge technology, no other place exists for training in that specialty.
What I didn’t know then was that the seeds of destruction were already sown with a small change in law the previous decade. In 1982 the Reagan administration eliminated the rules limiting company stock buy backs. In the past a company buying back their own stock to pump up the stock price was against the law as “stock manipulation”. Stockholders love them because of that jacked up stock price. About the same time companies started compensating executives with even more excessive amounts of stock, so executives love stock buybacks. Meanwhile to pay for the stock buyback, the company shorts money needed for research, training, and maintenance. The company sacrifices the factors it needs for its long-term survival for short term gain of a few. Companies have forgotten that in addition to stockholders, they also serve their customers, employees, and communities. Forgetting any one of a company’s constituencies has real world evil results. Consider deaths the 737 Max, or the Tesla self-driving mode, caused. Focusing on just the stockholders forces the company to focus on short-term results rather than safety, long-term growth and success in the long-term.
So what does this have to do with programming? People reading this blog are smarter than average. Smarter than average engineers are more likely to found their own companies or work in start-ups. When you have a chance to influence your company, please think about how you want the company to run a decade from now. Just because it’s legal doesn’t make it right for your company to follow the trend. Build your company to last, and you’ll be wealthy but not obscenely so, and you’ll make your community and country stronger — and you’ll still have a company that hasn’t robbed someone blind, or killed someone.
In the past I advocated leaving a company if the company won’t focus on quality. That position met a lot of resistance from people needing to feed their families and needing to keep a roof over their head. Happily, despite many short-term set backs, there are still plenty of tech jobs out there. The tech economy always grows in the long term — so I still advocate leaving a bad company, rather than ruin your career and reputation to be smeared working in that company. Here in the Silicon Valley, the idea has gained traction. The Great Resignation continues because companies not looking at the long-term over-emphasize short-term productivity and under-value creativity and innovation. Employees at the biggest companies in the Silicon Valley are unionizing (even though I fear they will find the most powerful union organizations are just another variety of corporation and corporate morals). Perhaps some companies still exist that benefit everybody and not just the executives.
In the meantime, lets talk some programming. Make more your life more tolerable with a good IDE (Interactive Development Environment). Over the years I’ve used several free IDEs and several expensive ones.
For free, you can still use emacs in electric-c mode. You can do the usual IDE things such as build and debug in emacs, but you’ll suffer through all the customization you need to do to make it usable.
Even better you may download Microsoft’s Visual Studio Code (aka VSCode) https://code.visualstudio.com/. I’ve taken a few classes to keep my C++ skills up-to-date, and they all used VSCode. VSCode is great for toy programs, but you’ll find yourself editing XML configuration files for anything major. It does not integrate well with major build systems.
Other free systems, such as CodeBlocks, https://www.codeblocks.org/, just haven’t been close enough to prime time for my use.
Eclipse CDT remains popular, but I found it painfully slow. You may pay money for a plug-in from SlickEdit to make it more modern with built-in and faster syntax checking, and code completion. SlickEdit also offers a fully integrated IDE (https://www.slickedit.com/). I payed the bucks for the “Pro” version for years but a year ago I gave up on Slickedit just because it didn’t keep up with the evolving C++ language, nor did it integrate with other build systems like CMake, Make, and Ninja. On top of that it depended upon an obsolete version of Python (fixed since then).
I now pay my money to the Jetbrains (https://www.jetbrains.com/clion/features/) for their CLion product. I love it is extensibility. Out of the box it supports CMake, and Make, and ninja builds. It also supports custom build commands. I’m sorry this sounds like an advertisement, but it is what I use. On Linux systems the latest version sometimes crashes, but I haven’t lost anything. It nicely integrates with Git and Github, and allows integration with other cloud services. Oh, it also supports Rust and Python.
Coding Ugly
A while ago I found this chunk of code in an old application:
struct Ugly {
int wordA;
int wordB;
int wordC;
int wordD;
};
...
int *word = &words.wordA;
for (int k=0; k < 4; ++k) sum += *word+;
At the time it looked wrong to me, and it still does, but because it was in "production" code, I left it alone because any change would trigger another cycle of QA testing. If the project had unit testing coverage, then I could have just changed it and maintained the functionality of the application. Factors that made the implementation wrong included the meanings, and hence the representations, of the components wordA, wordB, wordC, wordD, were likely to change, or even additional components could be appended. The engineer that wrote this actually said if those events happened, they would just re-write this code.
To fix this beast I should have written a unit test, and then turned the structure into an object. I could have blindly made an object that would implement an array, with specialized accessors for the components wordA, B, C, D. Rather I should have spent and extra hour doing a little analysis to determine the intent of the structure (Object Oriented Analysis), and then proceeded to Design and Programming. Khalil Stemmler has an excellent summary of the object-oriented programming cycle at https://khalilstemmler.com/articles/object-oriented/programming/4-principles/ .
Here is a more object-oriented look at the problem, giving tags (wordA, wordB, wordC, wordD) to the elements of the array, and protecting access to the underlying data:
#include <algorithm>
#include <array>
#include <initializer_list>
#include <numeric>
class Ugly {
private:
std::array<int, 4> words;
public:
Ugly(std::initializer_list<int> l) : words{} { std::copy_n(l.begin(), words.size(), words.begin()); }
auto wordA() const -> auto { return words[0]; }
auto wordB() const -> auto { return words[1]; }
auto wordC() const -> auto { return words[2]; }
auto wordD() const -> auto { return words[3]; }
auto sum() const -> auto { return std::accumulate(words.begin(), words.end(), 0); }
};
Its still ugly, because C++ doesn’t yet allow an std::array initialization from an initializer_list. A complaint I have about C++ is that new features seem to require a lot of bookkeeping code. Other languages, such as Rust, allow definitions of syntactic sugaring to avoid bookkeeping code.