Packages are named like that where there is (or was) a need to ease the transition between two major versions of a package, and the time needed to do so is expected to be long. During the transition period, both new and old versions are kept available, with the understanding that at some future time the older one(s) will be discontinued.
Sometimes the transition period is happening during the system release you're currently using. For some packages, it happens often enough that you can expect to see transitional package versions in every new system release. Software development tools often fall into this category, since upgrading to new tools on the same schedule as system releases may not be practical. My company's dependence on particular versions of GCC, Autoconf and Perl might be on a 5 year cycle, while my OS might be on a 3 year upgrade cycle. It therefore makes it easier for me to adopt new OSes if it includes my older versions of some packages in addition to whatever was current at the time the new OS was being developed.
Other times, these major version changes happened long ago, in the past, and now everyone is on the current version. This is the case with Apache, for example. The 1.3 to 2.0 change was a far bigger deal from a compatibility standpoint than any of the 2.x version changes, so once everyone was off 1.3, there was no longer a need to keep offering multiple Apache versions within a given OS release. But, once you've got everyone using the
apache2 package, there isn't a very good argument for renaming it back to just
apache. That would cause an unnecessary upgrade hassle. Besides, where there was a perceived need in the past to provide two parallel versions temporarily, the need will probably recur in the future.
This package naming practice typically happens only with libraries or important core packages. For more peripheral packages, you're expected to just upgrade to whatever's current at the moment.
Libraries are more commonly treated this way than applications because, by their nature, other packages depend on them. The more popular a library is, the more impractical it is to demand that every other package depending on it be rebuilt and relinked against it purely so that the library can be step-upgraded to a new major version without this transition period.
Often when an application is being treated this way, it is because it contains a library element. For example, Apache is not just a web server, it also provides a development API for the plugins. (
mod_foo and such.) If someone has an old
mod_something linked against the Apache 1.3 plugin ABI and hasn't upgraded it to use the newer 2.0 API, it's convenient if your OS continues to offer the old Apache 1.3 until all the plugin creators have a chance to update their plugins.