When your system is out of memory, you do not want to return an error to the next process that allocates memory. That might be an important process, it might have nothing to do with the reason the system is out of memory, and it might not be able to gracefully handle allocation failure (realistically, most programs can't).
Instead, you want to kill the process that's hogging all the memory.
The OOM killer heuristic is not perfect, but it will generally avoid killing critical processes and is fairly good at identifying memory hogs.
And if you agree that using the OOM killer is better than returning failure to a random unlucky process, then there's no reason not to use overcommit.
Besides, overcommit is useful. Virtual-memory-based copy-on-write, allocate-on-write, sparse arrays, etc. are all useful and widely-used.
OOM killer often doesn't run soon enough for me; I've even left the machine for twenty minutes and it's still swapping hard.
And I do say "often" because it does sometimes work.
I have set all my Firefox processes near-maximum priority to kill for the OOM killer, but it didn't help.
Also don't forget about memory compression: only meaningful with overcommit.