Actually, I have known this for some time, but today, it has bitten me again: Interpreted languages are not suited for application development. Period. Use them for quick hacks, or for prototyping, or in lieu of a shell script. But never for real applications.
People tend to say Computers are so fast today the overhead does not really matter, and if it does for a few inner loops, no problem: our language can interface with C. But that is beside the point. The real disadvantage of these languages is not their (somewhat inferior) execution speed, but their lack of static checking. If you write bogus in a compiled language, chances are the compiler will catch it. Some stricter languages will catch more kinds of bogus than more lenient ones, but there are surprisingly many ways to write bogus that every compiler will catch. Interpreted languages do not have a compile phase, they just throw an exception when encountering bogus at runtime. If they encounter it: There are many execution paths through a program, and some may not be followed very often, making it easy to write, install, and use completely broken software. You may say Well, write tests then, but as useful tests are, they come with large disadvantages when relied upon as the only means of detecting errors: Firstly, they have to be written. A compiler knows about the language, but the developer has to write all necessary testcases by hand. It is easy to overlook something, and it is also very easy to be lazy and write too few tests (or none at all). Secondly, executing tests takes machine time (probably more than what was saved by not compiling), and writing tests takes developer time (lots of it). Finally, the static analysis a compiler provides tends to catch different errors than tests do, so combining the two will simply catch more problems than either method on its own.
Oh, and then there is the problem of external code. Libraries, modules, whatever. APIs should not change (needlessly), but sometimes they do. With ordinary binary code, there is an established way to keep around different versions of a given library, so older programs using an older API can still function. I am not aware of a similar mechanism for Python, so getting ImportErrors from a module that installed just fine is not that unusual. In fact, implementing such a method for an interpreted language would be somewhat more involved than for a compiled one: When a programmer links to a shared library, the linker will take that to mean the latest installed version of that library. The version number is then encoded into the application binary, so the correct library will be used whenever the application is started. However, the very nature of an interpreted language means that the program is not touched by anyone but the developer. So if the developer does not demand a particular version, nothing else does, either. Seriously: use a tool that fits the job rather than clutching a hammer and trying to see nails everywhere.
Kein Kommentar • deutsch