| > if the program containing (symbol-name x) and (cos x) works in an interpreter but not in the compiler then the compiler is broken. The compiler isn't broken. The interpreter throws an exception, which meets your own definition of "works". The compiler gives an opinion "x has an inconsistent type". In this manner, the code also "works" in the compiler. You can still run the program if you like; then that opinion becomes an exception if an input case exercises the code, proving the compiler's opinion right. Compilers for dynamic languages do not preserve all interpreted behaviors. This is usually explicitly rejected as a goal: users must accept certain conventions if they want code to behave the same in all situations. For instance, some Common Lisp implementations re-expand the same macros during evaluation, which is friendly toward developers when they are modifying macros. But in compilation, macros are expanded once. Usually these compilation-interpretation discrepancies are obscure; we are not talking about obscure features here. It's a basic tenet of type checking in a compiler that it will flag things that will throw type-related exceptions at run time. You cannot say that type checking compilers for dynamic languages are simply not allowed because type mismatches are well-defined behavior; that's simply outlandish. |
> You can still run the program if you like; then that opinion becomes an exception if an input case exercises the code, proving the compiler's opinion right.
In this example, the compiler cannot give "x" the static type of "string" and also allow the program to handle errors when "x" is used in places where strings aren't allowed. If the static types don't match, the result is undefined; that's what static typing means.
If the compiler causes an exception to be thrown, then either:
- That's just an implementation-specific quirk, which just-so-happens to be the way this compiler behaves when it hits this undefined case; it's not part of any spec/documentation and useful only to hackers trying to exploit the system.
- We accept that the compiler didn't assign "x" the static type of "string" after all; it actually assigned it "string + exception + ..." (which may be the "any" type of the dynamic language, or some sub-set of it)