As a developer you most certainly have to jump into new codebases that were developed by others. When that happens, if you are lucky, you have the possibility to reach out to the developers that have worked on it and can guide you through the code.
I have seen something recurring in this process of knowledge transfer. The developer familiar with the code may often refer to it as "complicated". Hearing "It's complicated!" usually makes me think of relationships where obviously something is not right but nobody can put a finger exactly on the real problem.
Complicated is a peculiar word and I've started using negative words like this carefully when expressing a technical opinion. We, developers, are used to pay attention at each instruction we put in our code, so I feel we should start doing the same for words when communicating with others.
In many cases, we interchange complex and complicated, using them as synonym simply because they have a similar base and definition. Similar but not equivalent. Let's actually see what each means.
Definition of Complex:
involving a lot of different but related parts - difficult to understand or find an answer to because of having many different parts
Definition of Complicated:
involving a lot of different parts, in a way that is difficult to understand.
By looking at the definitions we see that they both share the concept of having many parts involved but the barrier to understand the element they refer to, lies in how these parts relates to each other.
Complex refers to related parts while complicated refers to different parts which implies they are unrelated conceptually between each other.
I think that these adjectives are extremely powerful to represent the status of a codebase.
A complex codebase is usually the result of many requirements that define the product. It might be hard to get a clear picture of the functionalities because they require a certain knowledge of the domain but at least the code models the domain with a proper design and correct software patterns. This gives the confidence that the code does not add an extra layer of logic on top of the domain; developers can infer and relate the business logic from the code with no particular difficulty. It does not mean the code is trivial obviously, but at least it does not put additional cognitive load on the reader besides the one of understanding the business logic behind it.
On the contrary, a complicated codebase can simply be the result of a bad development process. Code is not clear from an implementation stand point; even when the business logic behind it is trivial, understanding how that is implemented requires an additional and unjustifiable effort.
If we agree on this terminology, a lot can be conveyed by using these adjectives correctly. A developer who is getting onboarded on the codebase can understand what to expect and get an idea of what are the parts he can touch more confidently and which are more fragile.
For the developer familiar with the code, deciding whether to use one or the other should involve a level of introspection to understand the quality of the code which may have been overlooked because it was considered simply the result of a complex business logic.
Since I have started to pay attention to the difference of these two concepts I feel I have gained a powerful tool in my toolbox; I am now better at evaluating the status of a codebase and therefore provide better estimates for the work I am supposed to do it. Also this attitude helps shining a light on unseen technical debt and fuels discussions over design improvements.