Deploying newly developed features straight into a live production system is extremely risky, in whichever language or platform you choose, because you are not able to test the new features or changes before the current users of the system are exposed to them.
With this in mind, it becomes clear why you should at least separate production and development environment, and choose appropriate times to deploy (transport) from development to production.
However, there are also good reasons to separate even further, and have a testing environment as well. Since complex systems usually require manual testing to completely check it (which may even be done by a team of testers and/or the customer), having a separate test environment allows you to have a stable build of the system for manual/integrated/acceptance testing, while the development is free to continue at its own environment. By "stable", not only it means that the features were already unit-tested by the developers (at the development environment), but also for SAP R/3, it means that there will be no dumps because someone is activating development objects while there are users running them (LOAD_TYPE_VERSION_MISMATCH).