Often enough the thesaurus has a word that is closer to your notion, or several options that go different ways and you have to decide which you meant. As you say, once the word is picked it starts to influence the thing. If you pick a better word you get a better influence.
I’d say provide as much context as you feel appropriate and iterate if it’s too much or too little. That’s the problem, many developers are terrified of renaming things as they learn more. Renaming is only an issue if you have many external consumers depending on you.
>Particularly when the app changes over time and those abstractions evolve to be used in subtly different ways the programmer didn't foresee.
Perfect abstractions never go stale, they just become obsolete. TCP/UDP are timeless. Quicksort and hash tables are timeless. They are never renamed or changed. You may swap them out as necessary, but they’re complete.
The issue arises when people put too many responsibilities or contexts onto an existing thing. This manifests itself as objects with hundreds of properties or functions with dozens of Boolean flags to toggle on or off contexts. It’s a sad thing indeed.
In short functions that can be as simple as choosing a name like "_", "x", or "rtn" to indicate to future me that the thing being described isn't super well defined and is only useful insofar as it lets the containing scope do what it's supposed to.
In slightly longer sections of code I'll often just reference registers or memory offsets directly. You need some kind of identifier to access whatever it is you're working with, but if the name isn't pinned down well by English you might as well just pick your favorite number for the task.
Names are important in places, but only if they aid understanding of the code rather than (intentionally or not) subverting the reader from details that do actually matter.
Maybe those aren't great examples, but the point is, I think the problem of finding names that accurately convey the right mental picture of what the underlying abstraction is intended to do is much, much harder than just trying to avoid conflicts with names of builtins. Particularly when the app changes over time and those abstractions evolve to be used in subtly different ways the programmer didn't foresee.