I am tired of the perceived divide between interpreted languages and compiled languages, between scripting languages and programming languages, between the different roles of people who script and people who code.
There is no hard distinction between compiled languages and interpreted languages.
There are, if you must insist, languages that are usually compiled like C++, Pascal and COBOL and languages that are usually interpreted such as Smalltalk, PERL and Ruby.
Even then these categories are not rigid. Java, an extremely popular language, is usually compiled to bytecode, which is then interpreted on the Java virtual machine. This is not a new trick. Some early Pascal systems compiled down to a bytecode-like form called p-code. Python is also compiled to an intermediate form.
Sometimes a language's closest syntactic relative will be on the other side of the divide. For instance, PHP is a scripting language that closely resembles C.
As has been debated as response to the now-nuked flamebait node entitled "Writing PERL is scripting not coding", compiled or not doesn't change what it is that you do in writing the code. Both "scripting" and "coding" exercise the same set of skills. Both are programming. Interpreted or compiled is just a detail of the runtime environment, and it could change without even changing the source language that you code.
Any compiled language can in theory be run via an interpreter.
Any interpreted language can in theory be compiled. The fact that it can be interpreted is proof that it can be expressed as a sequence of machine operations, and thus can be an executable.
In a trivial sense that is always true, even for languages such as prolog that have no simple mapping to any existing machine language: the simplest way to do this would be to make an executable containing the interpreter bundled with the script's source as data. Running the executable would simply launch the interpreter with the included data.
This is not just theory, here are the examples:
Usually-compiled languages being interpreted - this is done either for teaching or for embedding purposes, or as a proof-of-concept for a new language before a compiler exists yet:
- We used a Assembler interpreter as a teaching tool when I studied Computer Science. OK, so it was only a baby instruction set for teaching purposes, but it needn't have been.
- A C++ interpreter called Cint exists here: http://root.cern.ch/root/Cint.html.
Usually-interpreted languages being compiled - this is more common as it is seen as useful for performance reasons:
- GCC 3.0 can compile java source to byte code, and byte code to a highly efficient executable.
- Perlcc produces executables from Perl source.
- LISP, a classic "interpreted language" is sometimes compiled.
Other sea-changes:
- Several other languages (e.g. Sather, Python, Scheme and Perl) have been compiled down to Java's bytecode. A Delphi to Java bytecode compiler has been demo'd but was abandoned as not being comercially viable. (Delphi is a proprietary, object-oriented, Pascal-derived, usually-compiled language).
-
Basic is an example of a language that has in various incarnations been interpreted, compiled and in the case of Microsoft Visual Basic, bytecoded.
- Microsoft's .Net includes a common language runtime where a large number of languages are compiled down to the same intermediate form
- C++ started life as a program called CFront, which translated C++ to C. Only later did one-step C++ compilers appear.
- Internet C++ is basically a C++ compiler that targets a portable virtual machine.
- The interesting case of Befunge and related Funge98 languages. This is a toy language supposedly designed to be hard to compile. However it can be translated to C. The C can then be compiled. What we have here (omiting a few details in the middle) is a process that takes source in Befunge in at one end, and emits an executable that corresponds to that source at the other. I would say that Befunge therefor is compiled using C as an intermediate language, much like early versions of C++.
- TenMinJoe says: Rather obscure example for you - Infocom's old text adventures were written in 'Inform', which compiled to 'z-code', which then ran on a virtual z-machine on a variety of platforms.
ssd's excellent writeup captures many of the reasons why a language should be designed as interpreted or not. However things can be more complex than this.
Interpreted languages are thought to be more portable, and this can be a reason for not compiling to an executable (see for instance, the Java Virtual Machine).
An interpreted language designed for scripting can have a syntax a lot like a popular usually-compiled language (usually C/C++), simply to leverage the familiar syntax, not because it is particularly suitable for interpretation. For instance, the PHP scripting language closely resembles a weakly typed version of C. See also Internet C++.
Kaleja says re CFront: while this is not strictly incorrect, cfront actually parses the C++, builds a syntax tree and symbol table, and uses C as the back-end target language. In particular, all compilation errors are caught by Cfront, not by the C compiler. if the C compiler catches an error, it's a Cfront bug, not a program bug. (source: design and evolution of C++ by Bjarne Stroustrup)
I am open to /msg's if you have any other good e.g.'s of languages crossing the compiled/interpreted line