It helps to have functions which take other functions and further arguments to pass on (e.g., map) use dot-prefixed arguments to avoid name collisions with those further arguments.
For example, this would be bad:
non_dot_map <- function(x, f, ...) {
map(.x = x, .f = f, ...)
}
non_dot_map(c("my", "your"), startsWith, x = "my dog")
# [[1]]
# NULL
What I want is list(startsWith("my dog", "my"), startsWith("my dog", "your")). But the x meant to be passed onto startsWith() will be caught by non_dot_map(). Honestly, I don't know how this returned anything at all, since c("my", "your") should've been passed to the .f argument.
It has nothing to do with name collisions in parent environments. If the function has an argument named x, then x in that function will always* mean that argument. If a function uses an argument named .x, then it could really mess things up when used with map.
Base R uses a different convention: all-caps. With the *apply() family, they have arguments like X, FUN, and SIMPLIFY. As far as I know, no other functions use those arguments.
* I'm sure there are ways to intentionally violate this assumption, but then you're asking for it.