> [!quote] There are only two hard things in Computer Science: [[💻 Programming/Cache Invalidation]] and Naming Things.
Along with [[💻 Programming/Cache Invalidation]], it's "one of the two hard problems".
This is not just restricted to computer science; Names are difficult and there's an entire philosophical discourse around it[^name-sep]. However, programming is unique as we are constantly expected to name things.
[^name-sep]: [SEP on Names](https://plato.stanford.edu/entries/names)
Naming is difficult because we're tasked to give a concrete description to an abstract concept. And this description cannot be too long as it would be inconvenient.
Once a concept is named, the name has a life of its own. There's an aspect of [[Realism]] in names; one can argue that certain things don't *exist* until they are named.
Just think about all the named concept we are surrounded by in mathematics, science, and engineering. At some point, someone came up with the names *function*, *factorial*, *derivatives*, *atoms*, ... Note that the *concept* of function is different than the *name* function. However, once a name is created and shared amongst the population, it now can be used as a building block for further constructs.
> [!example]
Another difficulty is that there may be a ==collection of related yet distinct concepts that need to be named==. A good example of this is physical units. In a written language, *force* ($kg\cdot m \cdot s^{-2}$), *energy* ($\dfrac{force}{time}$), and *power* ($\dfrac{energy}{time}$) can be used synonymously. However in physics they are distinct concepts, residing in their own hierarchy, devoid of their common English definition. Even though these terminologies are modeled after English words, the understanding of their original words are unnecessary, even harmful, to understand these technical jargons.
> [!example]
> The same problem arises with codebases. Codebases have their own hierarchies of abstractions that need to be named. Using UI programming as an example, a `Button` may belong in a `Panel` (so far so good), but multiple panels may be grouped into a ... `SuperPanel`? `Board`? Either way, it starts to get confusing. Coming up with a new name has the same problem as the physics unit problem. If one opts to `Board`, one is introducing the hierarchy of *button to panel to board* that is not intuitive from the English. However, `SuperPanel` feel descriptive and verbose (a common peril of enterprise software development) and raises the scalability question; what if the hierarchy increases again? do we call it `SuperSuperPanel`?
[[Design Patterns]]; I have mixed feelings against design patterns. Many times, they grandiose the work that's being done and actually obscures the system described in question. However, if used judiciously, design patterns provide a common language to describe the building blocks.
## Names have their own life #todo
Names dictate the future path of a component.
- name is created to around the concept / component.
- however, the code lives on with that name.
- afterwards, additional functionality is added to the component; as long as the new functionality adheres to the name, it's a good software engineering. otherwise, it may be a necessary hack.
# Solution; reduce the need
> [!note] Tailwind's philosophy
> **You aren’t wasting energy inventing class names**. No more adding silly class names like sidebar-inner-wrapper just to be able to style something, and no more agonizing over the perfect abstract name for something that’s really just a flex container.
> [tailwindcss - Utility-First Fundamentals](https://tailwindcss.com/docs/utility-first)
One answer to the naming problem is to reduce the *surface area* of naming things. This can be done in few different ways:
* [[Convention over Configuration]]
* Example: [[Go]]'s testing organization. tests reside in the same directory as code, with the `_test.go` suffix; this removes the need to parallel structure for tests.
* Allow unnamed objects.
* anonymous objects
* type inference - allows unnamed types to exist.
* structured typing (typescript, go)
* embedded types (typescript, go)
```typescript
interface Data {
id: string;
group_1: { ... }; // embedded type definition.
group_2: { ... };
}
```
* Addressing
* in most programming languages, entities must be explicitly named and declared in order to be referred to.
example: Object destruction syntax.
```typescript
// with destruction syntax
const [x, setX] = useState();
// without destruction syntax
const tmp = useState(); // this needs to be named.
const x = tmp[0];
const setX = tmp[1];
```
* Cleaning up named entities
* normally, unnamed entities cannot be `export`ed thus one can guarantee that it is scope-local.
* (yes, many languages allow you to control `export`s. However, in some languages, everything's exported. Example: CSS).
* namespace conflicts
* especially when names are used for exporting, names open up opportunity for conflicts.
* Example: CSS. Package names.
* A lot of times, this is solved by excessive namespacing.
* Individual layered entity having a name can be confusing.
* Especially if they have different types of names.
* Certain concept (ex: Currying) can reduce a class of names.
* However, currying has its own problem as an intermediate layer having a name can *reduce* confusion.
* `X`, `XFactory`, `XFactoryBuilder`
# Names created by its enemies
* Capitalism is a word created by socialist; [[Marxism|Marx]] frequently referred to "capitalist mode of production".