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

Of course, there is very little to stop someone from writing an interpreter for a compiled language or a compiler for an interpreted language, although there are some fundamental differences in the architecture of the language that might encourage either compiling or interpreting more. The purpose of this writeup is not to categorize languages as compiled or interpreted, but to explain why you might prefer to compile or interpret a program written in such a language.

There are many reasons why interpreting a typically compiled language may not be practical. For example, compiled languages typically do strong type checking, where variables are declared, and their types are well known once the program is compiled, to guarantee there are no runtime type mismatch errors. Also, there may be many forward references in a compiled program that can't be easily resolved without actually compiling it, or other sanity checks that would be too expensive to do at runtime. Interpreters of these languages would either have to partially compile the source, skip the checking, or suffer a huge performance penalty. Compilers also typically do optimization and other things that typically are not practical at runtime. Variable and function names between modules may need to be resolved and linked to make a complete executable. These and other differences don't make it impossible to interpret a compiled program, but they may make it impractical, or at least, very slow. Anyway, you could always compile to bytecode and interpret the bytecode.

There are many reasons why a typically interpreted language would be impractical to compile. Interpreted languages typically are weakly typed. Variables can change type on a whim, if the language even supports different types at all. Variables may come into existence just by using them. Linking of names between modules may change dynamically at runtime. The program might generate strings and feed them back to the interpreter for evaluation. Sections of code may even be replaced or added as the program runs. It may be possible to write a compiler for an interpreted language, but to do so, you just about have to include the whole compiler (or interpreter) in the executable. Sometimes the instructions for the interpreter are so simple that the overhead of compiling them just isn't worth the small optimizations gained from compiling. Anyway, you could always interpret compiled bytecode.

This, of course, describes the extremes. (There are always exceptions to extremes.) I'm sure there are many languages that fall close enough to center that they can be equally well (or poorly) compiled or interpreted. Some programs in extreme languages could easily be compiled, while others in the same language are nearly impossible to compile--just depending on the feature set they use. In languages with both compilers and interpreters available, you might want to use one or the other depending on what you are doing. For a list of bytecompiled vs. script languages, check out interpreted language.

Either way, it's still programming or coding or whatever you wanna call it.

Note also that compiling doesn't necessarily generate object code or executable; it may just emit bytecode or even source code in a different language. If you want to argue this, the first portable Unix C compiler emitted assembly code, which was then fed to the assembler. Gcc still does this, although many compilers today do produce machine code directly.

CFront (mentioned above) really just used the local C compiler as a glorified assembler, as if C was no more than portable assembly language.

Log in or registerto write something here or to contact authors.