8

In my compiler design courses, I have learned about and worked with a clear academic definition of an interpreter and a compiler, with an interpreter being

a program Pi from a language M capable of taking a program i from a language I and an input and executing i with the given input and the correct semantics for I on a machine capable of running programs from M

and a compiler being

a program Pc that, when given a valid program i from a language I as an input, produces a semantically equivalent program o in a language O

This definition would clearly put the usual execution of Java bytecode by a JVM in the domain of interpretation, no matter how much JIT compilation is done. (Of course, Java is also compiled before, from Java code to Java bytecode.) I have encountered opinions in discussions on this site that clearly and vehemently state the opposite, i.e. that Java Bytecode execution thingies are compilers. Since I am about to make the leap from academics to industry, I am a little bit confused here:

Is the above definition of interpreters false from the viewpoint of industry people in general? Or is it just false for Java people? Is the view of Java as a fully compiled language an alternate, but minority view? Or just a few loonies?

(PS: Please do not move this to cstheory. I have deliberately put this question here since I would really like to get the view of the professional industrial, not the academic community.)

6
  • 1
    Your definitions are practically useless. E.g., a CPU is an interpreter. Also, a discussion you're referring to was not only about a difference between interpretation and compilation, it was in context of a stupid prejudice about "interpretation" (whatever OP meant by it) being naturally much slower than execution of a "compiled" code. And, that discussion was about, specifically, bytecode interpreter, which is precisely defined. JVM is not a bytecode interpreter (for hot spots, of course). .NET CLR is not a bytecode interpreter at all.
    – SK-logic
    Sep 29, 2011 at 7:49
  • The key difference between an interpreter and a CPU is that a CPU is (part of) a machine. And yes, an interpreter running on a machine for its implementation language is indistinguishable (from the program's POV) from a machine for the language it is interpreting. That's the whole point of writing an interpreter. Thanks for the clarification of the context.
    – thiton
    Sep 29, 2011 at 7:56
  • you're pretending to be versed in CS (which is obviously far from being true). So please, give an exact definition of "being a part of a *machine*` (whatever it is), or stop picking on abstract terms at all.
    – SK-logic
    Sep 29, 2011 at 7:59
  • by the way, do you count ld.so (or any other dynamic linker) as an interpreter? If not - why?
    – SK-logic
    Sep 29, 2011 at 8:00
  • 1
    wow, now you've managed to smuggle "physical objects" into the clean and shiny world of a pure theoretical CS! And please, stop referring to an "intepreter". We've been discussing a bytecode interpreter. See the difference? It's at least 8 characters longer, you know.
    – SK-logic
    Sep 29, 2011 at 8:24

6 Answers 6

7

This definition would clearly put the usual execution of Java bytecode in the domain of interpretation, no matter how much JIT compilation is done. I have encountered opinions in discussions on this site that clearly and vehemently state the opposite, i.e. that Java Bytecode execution thingies are compilers.

Well, the two definitions aren't mutually exclusive. An interpreter can contain a compiler (in fact, most modern interpreters contain at least a bytecode compiler).

But I think the intuitive definition most people here use is something like:

  • a compiler creates native code that is then run directly by the CPU
  • an interpreter has some kind of "interpreter main loop" that reads instructions (either source code statements or something like precompiled P-Code or bytecode) and performs instructions accordingly.

By this distinction, an "interpreter" is usually an order of magnitude slower than a "compiled" program. So when we're talking about performance, this definition is more useful than the classic CS definition.

4
  • 5
    A java compiler definitely is a compiler, yet it doesn't produce native code. Same for .net compilers. Therefore, your definition of compiler is plain wrong.
    – user281377
    Sep 29, 2011 at 9:57
  • 3
    A java compiler produces code that is native to the JVM, therefor, it's a compiler.
    – Dabu
    Sep 29, 2011 at 12:53
  • @aamoQ: Yes, according to the formal CS definition, javac clearly is a compiler. And the CPython bytecode compilation step is a compiler, too. Yet people intuitively call CPython an interpreter, and I think they used to call Java "interpreted" when JVMs didn't have JITters yet.
    – nikie
    Sep 29, 2011 at 15:59
  • @nikie That's because javac is a compiler and the jvm (java) is an interpreter for java bytecode.
    – Bergi
    Oct 24, 2021 at 14:47
3

From Michael Scott's Programming Language Pragmatics, Third Edition.

The high-level explanation of compilation is:

The compiler translates the high-level source program into an equivalent target program (typically in machine language), and then goes away. At some arbitrary later time, the user tells the operating system to run the target program. The compiler is the locus of control during compilation; the target program is the locus of control during its own execution.

A high-level explanation for interpretation is:

Unlike a compiler, an interpreter stays around the the execution of the application. In fact, the interpreter is the locus of control during that execution. In effect, the interpreter implements a virtual machine whose "machine language" is the high-level programming language. The interpreter reads statements in that language more or less one at a time, executing them as it goes along.

However, some language implementations also mix compilation and interpretation, so the lines get a little more blurry. In such an instance, the source program is translated into an intermediate program that is run by a virtual machine. The source code is compiled, and the output of compilation is interpreted.

Compilation happens when a translator thoroughly analyzes the input source files and creates some output that does not resemble the original source. That means that compilation requires, according to Scott, "analysis and nontrivial transformations".

9
  • Most of the Common Lisp implementations are simple and straightforward native code compilers. But, compiler stays around in a runtime as well, so you can generate and compile more code if needed. Is it an "interpreter"?
    – SK-logic
    Sep 29, 2011 at 10:04
  • @SK-logic I've never used Common Lisp, so I can only read what Wikipedia says and any other Internet resources (including your comment) on the subject. According to Wikipedia, both compilation and interpretation of the language are supported. From Wikipedia, it reminds me of the JIT compilation of Java, where the compiler can be invoked during interpreted execution of the language, but I'm not familiar enough to say that is an accurate description and I can only speak to languages that I know how they work at some level.
    – Thomas Owens
    Sep 29, 2011 at 10:09
  • implementations like SBCL do not provide any forms of interpretation. There is only a native compiler available, and (eval ...) first compiles into native and then runs the resulting code directly. Another similar case: top-level REPLs for compiled languages. They're available for even C and C++, for Haskell, etc. No "interpreters" there - it is just a compiler which stays available.
    – SK-logic
    Sep 29, 2011 at 10:16
  • @SK-logic But the compiler is a separate application or process (or even thread) that is invoked, comes to the foreground, performs its compilation, and then returns to the background? If that's the case, it still fits the definition above. The compiler process takes over, performs its work, and then the application is executed - two distinct loci of control.
    – Thomas Owens
    Sep 29, 2011 at 10:37
  • 1
    no, compiler is a function, available in the same process context. A compiled code is written directly into a memory, without intermediate files and such.
    – SK-logic
    Sep 29, 2011 at 10:39
3

Is the above definition of interpreters false from the viewpoint of industry people in general?

No

Or is it just false for Java people?

No

Is the view of Java as a fully compiled language an alternate, but minority view?

No

Or just a few loonies?

No

The Java execution environment is more complicated than is envisaged by those theoretical CS definitions. But both theoreticians and practical developers are cool with this.

Theoretical definitions like these are designed for a particular purpose; i.e. formal reasoning about how programs are "compiled" and "run". If you need to model Java in that way, and include JIT compilation in the modelling, then there are ways to handle this. For instance you could make "call native compiled method" a primitive operation of the interpreter.

The reality is that the Java execution platform uses both compilation and interpretation in both the intuitive and theoretical sense. So if you need to model the Java platform to that level of detail, you need to incorporate this into the modelling.

2
  • I'm not 100% sure that "theoretical CS definition" is right. I'm not sure they're theoretical. They're "conventional definitions" or perhaps more accurately "traditional definitions". "Theoretical definitions like this" might just be "Distinctions like these". The "intuitive and theoretical", however, is an excellent point, and should be highlighted.
    – S.Lott
    Sep 29, 2011 at 10:51
  • I'm not sure what you are saying, but I am taking it on face value that the OP has actually encountered the quoted text as definitions. And they are using terminology and phraseology that a theoretician would recognize.
    – Stephen C
    Sep 29, 2011 at 12:38
1

I generally consider any program that parses and converts code into a lower level form a compiler. So I'd definately consider Java a compiler. As would be C#, Python, PHP, etc compilers, as they all reduce source code down to bytecode, which is then executed. C++, Delphi, and a few others that compile directly to natively executed code I'd call (and I see a lot of people call) 'native code compilers'.

An interpreter, at least the way I learned it way back when, is a program that parses lines of a script one at a time and executes them directly. That is, there's no intermediate or lower level code. I'm not aware of any 'modern' languages that are interpreters.

Regarding your definition of 'compiler', I dont think that necessarily implies that Java code isnt compiled. You just need to interpret 'language O' as the bytecode instruction set.

3
  • Yes, I and my definition would agree with that, thanks for the answer. The interesting thing is that some people even seem to insist that the JVM is a compiler, while it seems a clear case of an interpreter to me. Updated the question.
    – thiton
    Sep 29, 2011 at 7:45
  • @thiton, are you really incapable of recognising the difference between a generic, broad definition of an interpreter and a very specific thing, namely, bytecode interpreter? Or you're just trolling? Your CS knowledge is obviously quite limited, otherwise you'd noticed that any modern compiler is an interpreter as well (e.g., constant propagation and agressive DCE counts as interpretation).
    – SK-logic
    Sep 29, 2011 at 7:56
  • While such things aren't necessarily relevant today, it may be worthwhile to distinguish systems which transform a text file which is retained into some other form prior to execution, versus systems where the development system translates code into some other form as it is entered and translates it back when asked to display it. In the latter case, the processed form would be the source code.
    – supercat
    Feb 16, 2014 at 22:46
0

From practical point of view you can think that something is interpreted as soon as you can do this pseudo code:

a = 6
b = 7
eval("c = a + b")
print c

I will not discuss security issues, best practices when to use and when not to use eval and so on.

JVM and .NET allows (with some call to standard library functions, wrappers and other issues) to compile code on the fly:

a = 6
b = 7
assembly = my_implementation_of_eval("function sum(x,y) { return x + y} ")
print assembly.call("sum",a,b);

But that is just a compiler with ability to dynamically load a module. Compare deep integration to local vars and creating new variables in interpreter.

1
  • You can do essentially the first set of code with a Lisp system, including those that don't have interpreters and rely completely on compilers (like SBCL). Sep 29, 2011 at 20:50
0

A Compiler usually translates something from language A to language B. Language B can be machine code (for an existing or virtual CPU), but there are compilers that output source code in a different language.

An Interpreter usually executes a program written in language X.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.