Sometimes we ignore details to get a task done. Frances Buontempo considers how much more there is to programming than just code.
Overload reserves two pages for an editorial, and I somehow manage to fill them, even though I can never think of a suitable topic. What are the two pages for? An opinion piece? Something topical? Maybe I’m just being a coward and avoiding controversial subjects. Or maybe it is really hard to write to order on a regular basis. I have got away with this for a long time, though. I become editor in 2012. My first attempt at an editorial was entitled ‘Allow Me To Introduce Myself’ [Buontempo12]. I mentioned then it was hard to think of a topic, or what to do with the two pages. Nothings has changed.
I’m sure we all have examples of being given something we couldn’t figure out how to use, though maybe not two pages for an editorial. I was given a stationery tray when I started a previous job, including pens, notepads and a bottle of Tipp-ex. I’m not sure the Tipp-ex would have been that useful for correcting incorrect code. I also suspect some readers may never have seen a bottle of ‘correction fluid’. Arcana slips into various places in IT. The save icon is still often a floppy disc. Some forms still have a space for a fax number. Technology changes are very fast paced, so ‘old’ tech might mean something from a few years or decades ago. How many SCART cables do you have stored in a cupboard? In other disciplines, change is slower – so the almost immediate obsolescence doesn’t take hold in the same way. Historical reasons are still permeate, but in a different way. A plumber no longer works with lead, though the name has stuck: plumbum means lead, and a plumbarius works with lead [etymonline]. I’m sure you can think of other examples.
Historical artefacts are one thing, but often there are more things lurking than you first realise, no matter what you are trying to do. When you try to write code, you often find you need to learn extra concepts and idioms. Just copying code from the internet or using GenAI might get you somewhere, but at some point you need to engage your brain and think about what you are doing. Programming jobs themselves can come with unexpected aspects, like FORTRAN lurking in the stack call, or finding yourself on-call. Software itself often has surprising elements which can be hard to figure out. You will either need to learn how to drive an IDE or an editor and a shell or prompt. You might accidentally learn how to type a bit. You might end up arguing about whether mechanical keyboards are the best, or which editor to use. You might have to learn bug tracking software, or produce a Gantt chart for your final project. (Do people still make Gantt charts – yes they do!). You might have to learn how to operate a high tech telephone, or discover how to press + on a numeric keypad. None of us signed up for this!
Software brings other surprises too. Moving from working on a project on your own in a small group as a student to finding your way around a large software system in your first job can be overwhelming. Code tends to accrete, erm, ‘unnecessary’ functions and the like over time. There are several ways to start finding your way around an unfamiliar code base. If you can’t immediately see what a function or class is for, try deleting it and see if you get compiler errors. That’s easier with C++ (at the moment) – I tried this on a C# code base, and various parts were only used via reflection, so that was confusing. Michael Feathers wrote about scratch refactoring in his Working Effectively with Legacy Code book [Feathers04]. You deliberately refactor code, then throw away your changes, allowing you to discover how the parts hold together. Rolling your sleeves up and tinkering is often a good way to think systems through and learn. You are unlikely to figure out how something works by listening to someone else tell you about it. I have had several contracts where a dev lead took new hires to a room and told them about the code, pressing short-cut keys for ‘go to definition’ or ‘go to usage’ in an IDE. Most of us can manage to press a key ourselves. The best onboarding came from the tech lead sitting with me and us refactoring a small function. Doing something together can be so much more informative that talking about it.
Each programming language tends to end up too big to hold fully in your head. There are many features in C++ I haven’t used often. I was asked when I had used dynamic_cast
at an interview once. My honest answer, at the time, was I hadn’t. The interviewer was surprised, but talking it through we decided you could often end up with a cleaner design if you avoid dynamic casts. In a different interview I was asked if I had used custom allocators to speed up code, and I hadn’t. I still haven’t used them often, but have seen them speed up code. I’d need to look up the details to jog my memory if I wanted to use them again. Having an awareness of something means you can just about answer the question, “What’s this for?” However, that is not the same as being able to use the feature easily.
Switching between programming languages can be confusing too. You might have a mental model of how one thing works, and make assumptions about similarities when you find something similar in another language. C++ classes have an implicit this
pointer to refer to the current instance. What’s this
for? Many times you don’t need to use it directly, but implementing copy or move assignments will force your hand. Python, in contrast has an explicit parameter for instance methods, usually called self
by convention. Each instance method takes a first parameter referring to the current object. The self
isn’t a keyword, but most people use this. The subtle difference between keyword or not and implicit versus explicit isn’t too confusing, but might catch you out for a moment if you switch between the languages a few times. C++23 introduced deduce this, which is a newer C++ feature I have never used [Brand22]. Sy Brand refers to these as “explicit object parameters”: you add a function starting with a this
parameter, which gives you a way to write one function for const/non-const, and rlavues/lvalues, rather than needing four overloads. Maybe I shouldn’t get started on JavaScript’s this
binding quirks. Strict mode makes this
switch from some global object to undefined [Stackoverflow]. Also arrow functions (think lambdas) don’t have a this
themselves but might find one in lexical scope [Mozilla]. Naming between programming languages differs too: list or array or vector? It depends.
Aside from language quirks, trying to build code can be a challenge. If you’re lucky, there’s a CI/CD pipeline with a script that just works. However, that’s often not the case. And you might need to wait for a tool licence, or fill in forms to install a package. There’s more. C++ has several rival package managers, and modules promise ways to speed up builds. Write up an article about either if you are using them successfully: some people are, but I’m just watching from the sidelines for now.
Some people exclusively use an IDE and don’t know the details of how a build works. Which is fine, to a point. I recently read a reddit post [Reddit] from someone saying they are a hobby programmer and know how to drive Visual Studio but don’t know where to start on other platforms. I started my programming career with embedded coding, so learnt various build tools from the start. I personally like to find out how to build something from a prompt, just to get a feel for what’s happening. I should probably learn CMake properly one day, but I am just watching that from the sidelines too. IDEs can help you be more productive, but it’s useful to understand a bit of the details. And sometimes upgrades move your IDE’s button, which is very irritating. Or sprout new buttons – leaving me wondering what the new buttons are for. I notice my Visual Studio upgrade is offering me GitHub Copilot. I shall avoid this for now.
Different programming languages and varying build systems may leave you wondering what various parts are for. Things can get even more complicated if you also have feature flags. You have probably heard of the Knight Capital Group feature flag fiasco [Wikipedia-1]. Reusing an old feature flag without fully understanding what it did, or where it might be loitering in old code that hadn’t been upgraded, led to an expensive round of buying stock by mistake. The moral of that story might be remove feature flags as soon as possible. Such flags are one type of global state that makes code hard to reason about. Feature flags aren’t the only way to break code. Locales can cause confusion too. If your build server has different settings to your machine, you might see flaky tests – ones that pass with one locale but not another. Global state can also lead to race conditions in parallel code and further flaky tests that sometimes pass, but only sometimes, on the same machine. If you find a flaky test, first ask if you need it, and if you do try figure out why it sometimes fails. If you leave such a test in a codebase, it will get ignored. Try to nudge it to something reliable. I traced some confusing behavior to a Singleton once, another form of global state. By adding a reset
method, calls to tests weren’t affected by the run order. You can sometimes find a small change that makes your life easier.
The whole ecosystem of programming involves a lot more than just the code. Coding guidelines vary between companies or even teams, so you might need to be flexible if, like me, you often contract. Build systems vary wildly too. Even if you are settled in one role for the long term, or have full control over your setup because you are a hobby programmer, tools change and the languages evolve. I suspect as programmers, we are frequently faced with change in ways that some other professions or hobbies are not. Maybe this keeps our brains more plastic: I’m no brain surgeon or psychologist, but neuroplasticity seems to be important for cognitive function [Wikipedia-2]. Adapt and survive, so the saying goes. Trying to keep up to date is a challenge. C++, and any programming language, will always contain features and aspects you don’t fully understand yet. Feel free to ask “What’s this for?” The accu-general email list is a friendly place to ask questions. You might even inspire someone to write an article for us. You will always have things you don’t fully understand. That’s OK. You could delegate to someone else, pair with them, or ask AI. But, whatever you do, stay curious and keep on learning.
References
[Brand22] Sy Brand, ‘C++23’s Deducing this: what it is, why it is, how to use it’, June 2022, https://devblogs.microsoft.com/cppblog/cpp23-deducing-this/
[Buontempo12] Fran Buontempo, ‘Let Me Introduce Myself’ in Overload, 20(110):2-3, August 2012, https://accu.org/journals/overload/20/110/buontempo_1904/
[etymonline] Plumber: https://www.etymonline.com/word/plumber
[Feathers04] Michael Feathers, Working Effectively with Legacy Code, ISBN 10: 0131177052 / ISBN 13: 9780131177055 Published by Pearson, 2004
[Mozilla] Arrow functions: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
[Reddit] ‘I use Visual Studio to write C++ and nothing else. I have no idea what command lines, CMake, or any of that stuff is - where can I find information on how to move forward?’: https://www.reddit.com/r/cpp_questions/comments/1lov0in/i_use_visual_studio_to_write_c_and_nothing_else_i/
[Stackoverflow] ‘Default binding of the this keyword in strict mode’, available at http://stackoverflow.com/questions/49023201/default-binding-of-the-this-keyword-in-strict-mode
[Wikipedia-1] Knight Capital Group: https://en.wikipedia.org/wiki/Knight_Capital_Group
[Wikipedia-2] Neuroplasticity: https://en.wikipedia.org/wiki/Neuroplasticity
has a BA in Maths + Philosophy, an MSc in Pure Maths and a PhD using AI and data mining. She's written a book about machine learning: Genetic Algorithms and Machine Learning for Programmers. She has been a programmer since the 90s, and learnt to program by reading the manual for her Dad’s BBC model B machine.