This doesn't really touch on what I think of when I think of "naming things is hard", which is not really technical or language-specific so much as semantic. When you name an abstraction (object, enum value, function name, etc) you are baking in assumptions about that abstraction that may not make sense a few years down the line. When the user connects to the websocket server, is that a Connection or a Socket or a SocketConnection or what? If they disconnect and reconnect, is that a Connection with two Sessions, or a Session with two Connections, or something else? Can a Connection be disconnected? Etc.
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.
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.