Have you ever wondered what makes code “dirty,” what refactoring entails, and why there are no silver bullets in programming? I’ve compiled a glossary with brief explanations to help you gain an overview of some of the perplexing phrases often used by programmers. If something is missing that you’d like to see explained in the glossary, feel free to leave a comment, and I’ll be sure to add it.
I divided the glossary into the following sections:
- Code Quality
- Code Structure
- Programming Language Attributes
An algorithm is a set of step-by-step instructions for solving a problem or performing a specific task. It’s a fundamental concept in computer science and is used in a wide range of applications.
Algorithms can be evaluated based on their efficiency, accuracy, and suitability for a particular problem or task.
An error or unintended behaviour in a program.
The term originated at the time when computers were large machines containing vacuum tubes. In 1947 Grace Hopper (computer scientist) found an actual bug in the Harvard Mark II computer, which caused a malfunction. The term ‘bug’ has been used before to refer to any kind of problem but this incident popularized the term.
A hack refers to a quick solution for a problem that works at the moment but cannot be maintained or modified in the future. Hacks can be helpful in situations where time is of the essence, but can also lead to technical debt if they are not replaced with a maintainable solution in the long run.
Refactoring is the process of restructuring code to make it easier to understand, modify, and maintain. It can also be used to describe the process of adjusting old code to new requirements. Although the term “refactoring” implies that the code was in good shape to begin with, this is often not the case. Refactoring is often necessary for removing poorly designed code.
A silver bullet refers to an ideal solution that is easy to implement, solves all problems, and delivers perfect performance. However, such a solution does not exist, and the phrase “there is no silver bullet” is often used to caution against endless searches for a perfect solution that may not exist.
Hardcoding refers to the practice of embedding fixed values directly into a program’s code, rather than using variables or configuration files. This means that the values cannot be changed without modifying the code and recompiling the program.
Hardcoding can make code less flexible and maintainable, and should generally be avoided in favour of more dynamic solutions.
Magic numbers are hardcoded values that lack clear context or meaning, making the code difficult to understand and maintain. These values can appear in various forms, including integers, floating-point numbers, and other data types.
It’s crucial to avoid using magic numbers in code as they make it harder for other programmers to comprehend the code’s purpose and function. The best practice is to assign these values to variables and name them to make the code more readable.
Clean code refers to code that is easy to read, understand, modify, and maintain. Conversely, code that lacks in one or more of these areas is commonly referred to as “dirty” code. Clean code is often used to describe well-written code. The concept of clean code is subjective and often causes debates online, with many nuances as to what constitutes as clean or dirty code.
Although Robert C. Martin did not invent the term, he popularized it through his book series titled Clean Code. I would recommend reading these books, as they are both informative and entertaining.
Technical debt refers to the cost of making short-term decisions that create problems for the long-term maintainability of a codebase. This can include bad code, hacks, and other shortcuts that accumulate over time and make it difficult to change the codebase without breaking existing functionality.
Technical debt is difficult to remove and can quickly become overwhelming, making it important for programmers to prioritize writing high-quality code to avoid incurring technical debt in the first place.
Code smell refers to code that appears to be problematic or poorly structured, even if the code technically functions correctly. It is an indication that the code contains design flaws or potential bugs that may not be immediately obvious, but could cause problems down the line.
Legacy code refers to older code that is still in use, but whose internal functionality is poorly understood or documented. This may occur when the original developers are no longer available and the code has not been well-maintained or documented.
The term has a negative connotation, as legacy code is often difficult to modify, update, or maintain due to its outdated design, lack of documentation, or other factors.
A derogatory term for poorly written or incomprehensible code that is essentially “doomed” to become legacy code from the moment it is written. It’s a strong insult towards the author of the code.
Software Decay |
Software decay refers to the gradual degradation of code over time, leading to a state of disrepair and obsolescence. This occurs when existing code is not updated to keep pace with evolving standards and requirements.
Preventing software decay requires regularly updating the code base, replacing outdated frameworks and plugins, and adhering to best practices for code maintenance. Code that is poorly designed or implemented is more susceptible to software decay than code that is well-crafted.
Rotten code refers to code that is of low quality and has been left in a codebase without proper documentation or maintenance. It is often unclear why the code was added in the first place and whether it is still necessary or in use.
Rotten code can lead to increased technical debt and make it difficult to modify or maintain the codebase. It may also be prone to bugs and other issues due to its poor quality. In some cases, rotten code may be so problematic that it needs to be completely removed from the codebase in order to avoid further issues.
Code Architecture typically refers to the overall design and organization of a software system or application, encompassing the relationships and interactions between its various components. In larger projects, a well-defined code architecture is essential for providing a high-level understanding of the entire system. Professionals who specialize in this area are known as code/system architects.
Design patterns are proven, reusable solutions to commonly occurring programming problems. They provide a structured approach to software design and aim to improve code quality, maintainability, and scalability. The concept of design patterns was introduced as a way to codify best practices and facilitate communication among programmers.
The “Gang of Four” book, “Design Patterns: Elements of Reusable Object-Oriented Software,” is a classic reference that introduced many important patterns. Although it can be a challenging read, it remains a valuable resource for programmers.
Boilerplate is code that is repeated in multiple places with little variation to achieve certain functionality. It doesn’t generate any value but is needed for the code to work like it is intended.
Examples of boilerplate code are functions to get and set instance variables.
The process of searching for bugs in a program.
Rubber ducking is the practice of explaining your programming problem to another person or object, often a rubber duck, in order to solve it. The explanation can be given to anyone, regardless of whether they understand the problem or not. The act of organizing your thoughts and vocalizing the problem can often help you find the solution.
The term comes from the book “Pragmatic Programmer,” which tells the story of a programmer who used a rubber duck to debug their code. I think the book is not relevant for modern programming practices but the concept of rubber ducking remains useful.
Sanity checks refer to quick tests to verify that something works as expected. You test your most basic assumptions and work up from there to your current problem. They are also useful when verifying if you have actually done something you thought you have already done/checked.
For example, after writing to a variable, check if the value actually changed to catch any typos or mistakes. Don’t expect it to change, check it.
Programming is a complex task and as you get more experienced you tend to miss mistakes by glancing over simple parts of the program. Sanity checks can help you to find those mistakes.
Dot-driven development is a practice in which programmers use the auto-completion feature of their IDE to browse the available methods and properties of an API.
To do this, they type a dot after the object they want to know more about, and the IDE displays a list of available options. This approach is popular for quickly searching an API without needing to consult the documentation. It can also be helpful for finding a specific function if you don’t remember its exact name.
Describes the practice of optimising code before knowing if the performance is a problem. Optimization is important but you should only optimize code that you know is a performance problem. Profile or do benchmarks before optimizing. Otherwise, you reduce the readability of the code and waste time that could be used to enhance the performance of critical code.
Integrated Development Environment (IDE) refers to a software application that provides a complete environment for software development, testing, and debugging. It typically includes a code editor, debugger, compiler or interpreter, and build automation tools. IDEs help programmers to streamline their workflow, reduce errors, and increase productivity.
Examples of popular IDEs include Visual Studio, Eclipse, Rider, PyCharm, and Xcode.
A program that is used for modifying text files. It can include features such as syntax highlighting and formatting. All IDEs contain text editors, but not all text editors include the additional features that make an IDE. Notepad++ is a popular text editor.
A debugger is a software that helps you to find bugs in your code. It provides you with the ability to see the flow of the program, inspect variables, halt the program at specific code lines, and much more. Most of the time, the debugger is integrated with your IDE, but there are also standalone debuggers available.
A compiler is a program that translates source code written in one programming language into another language or machine code. This is typically done from a high-level language to a low-level one. Compiling involves several steps. Compilers are usually integrated with an IDE and there are different compilers for each programming language.
An Assembler is a program that turns code written in Assembly (programming language) into machine code. The process is called ‘to assemble’.
An assembler is something different from a compiler because the instructions written in Assembly are mapped one-to-one to binary code. A compiler in contrast maps one high-level instruction to multiple binary instructions.
An interpreter is a program that reads and executes code at runtime. Unlike a compiler, which translates the entire program at once, an interpreter does it line by line, making it slower but more flexible.
Interpreters are commonly used in scripting languages, such as Python and Ruby.
Historically, the terms ‘terminal’ and ‘console’ described different things. A terminal was a device used to enter and display data, while a console was a physical machine used to control and manage a computer system.
Today, both terms are used to refer to text-based interfaces that interact with the computer’s operating system. The general term for this kind of program is CLI, which is an abbreviation for Command Line Interface.
Some examples of CLI are the Command Prompt on Windows PCs and the Terminal on Unix-based systems like Linux and Mac.
API stands for Application Programming Interface and refers to a set of protocols, routines, and tools used to build software applications. It allows different software systems to communicate and exchange data with each other
Programming Language Attributes
A language that is executed directly by an interpreter without compiling it into machine code.
A language that is translated by a compiler before execution.
Examples: C, Swift, Fortran, Java
Low-level languages are programming languages that are close to the machine code and run on a specific type of CPU. They provide direct access to the computer’s hardware, such as memory and registers, and offer a high degree of control and execution speed. Due to the level of detail required to program in these languages, they are typically more challenging to learn.
Low-level languages are commonly used in developing device drivers, operating systems, and other system-level software.
Examples: Assembly, Fortran, C
High-level languages are designed to be more human-readable and use abstractions and syntax that are closer to natural language than machine code. Unlike low-level languages, they provide less control and have a lower execution speed.
High-level languages are commonly used to write application software, games, websites, and other types of software that do not require direct control over hardware.
It depends on your view on which languages classify as low- or high-level. There is a lively debate online on where to place some languages on the spectrum. For an Assembly programmer, everything else is high-level because they write machine code. But a phyton programmer may regard C# as low-level, even so, it’s a language where you don’t have to manage the computer memory yourself.