4

I've read that fsi.exe (F# Interactive) is not a true "interpreter" in the strict sense because it compiles F# code on the fly and displays its output.

I am under the impression that the word "interpreter" applies to "dynamic" languages (i.e. JavaScript) and therefore does not apply to F# since it is a compiled language.

Is this a fair assessment? Or can compiled languages be "interpreted"? Or is this just a semantics issue?

Appreciate any help.

The Internet
  • 7,959
  • 10
  • 54
  • 89
  • 2
    Languages aren't compiled or interpreted, they are specified. Programs implementing these specifications may be compilers, or interpreters, or both. There are, in fact, interpreters for the C programming language and ahead-of-time compilers for very dynamic languages such as C. Review your terminology! –  Dec 30 '11 at 15:25
  • 1
    Semantics. C# certainly isn't interpreted (normally). Check 40 minutes into this video http://channel9.msdn.com/events/BUILD/BUILD2011/TOOL-816T – Hans Passant Dec 30 '11 at 15:42

5 Answers5

4

A difference between compilation and interpretation is blurred. Many languages perceived as "interpreted" are in fact often compiled to a native code (e.g., JavaScript with v8). Some implementations of the most dynamic feature of the dynamic languages, eval, are just wrappers around a compilation (e.g., in SBCL).

And of course REPL has nothing to do with compilation or interpretation, REPL can be built on top of any execution model. fsi is just a REPL, and it is using the same F# compiler core as fsc.

SK-logic
  • 9,605
  • 1
  • 23
  • 35
  • 2
    -1: "A difference between compilation and interpretation is blurred". The difference may be a source of confusion but it is clear, not blurred. – J D Jan 01 '12 at 08:54
  • 2
    @Jon Harrop, it is "clear" for you. Others won't agree. There is no clean and *widely accepted* definition. You should have known better. – SK-logic Jan 03 '12 at 10:29
3

I am under the impression that the word "interpreter" applies to "dynamic" languages (i.e. JavaScript) and therefore does not apply to F# since it is a compiled language.

Is this a fair assessment?

No. The word "interpreter" refers to the way in which a program is executed. If a source program is executed by running it through an independent program called the "interpreter" that executes it by interpreting the meaning of each instruction in the source program then it is interpreted.

The term "dynamic programming language" appears to have no formal definition and is just used informally often to refer either to a dynamically-typed language (i.e. one that lacks a static type system and, therefore, defers all type checks to run-time) or a programming language implemented such that it is capable of feats at run-time such as macros, reflection, REPLs and so on. This has nothing to do with whether the programs are interpreted or compiled. For example, Common Lisp is regarded as a dynamic language and OCaml is regarded as a static language (although it has both macros and a REPL) but both interpreters and compilers are available for both Common Lisp and OCaml.

Or can compiled languages be "interpreted"?

Again, the term "compiled language" is ill-defined. Any language can be either interpreted or compiled. Formally, any executable language can be interpreted and any interpreter can be turned into a compiler by partially specializing it over a source program.

Note that some programming language implementations use both compilation and interpretation simultaneously in order to get some of the best of both worlds. For example, OCaml can compile programs to a bytecode using a compiler written in OCaml and that bytecode is then interpreted by an interpreter written in C. This has several advantages:

  • Much faster than an ordinary term-level interpreter.
  • Much simpler than a native code compiler targetting a machine code like x86.
  • The compilation stage can perform optimizations (e.g. big-step semantics) that the interpreter benefits from without ever having to see.
  • Simplicity makes it tractable to write the interpreter in C, further improving performance.

Or is this just a semantics issue?

Terminology.

Community
  • 1
  • 1
J D
  • 48,105
  • 13
  • 171
  • 274
  • Your definition of "interpretation" is nothing but your own personal definition. By some definitions, for example, Qemu is an interpreter. – SK-logic Jan 03 '12 at 10:33
  • You can say that of any definition. Can you give a concrete example where this is not completely clear cut? – J D Jan 03 '12 at 16:15
  • 1
    firstly, your definition is recursive: "*interpreter ... executes by interpreting*". Secondly, many things which are called an "interpreter" won't fit any possible interpretation of your definition - e.g., V8 is still called an "interpreter" despite being a tracing compiler, or even worse, a trampoline mini- *interpreter* often found in CPS implementations, which has absolutely nothing to do with "interpreting the meaning", whatever it means. – SK-logic Jan 03 '12 at 16:40
  • Saying that programs are interpreted by interpreting the statements within them is not a recursive definition. Google's V8 webpage explicitly states that "There are no intermediate byte codes, no interpreter". If other people then misuse these terms that does not reflect upon their definitions as you imply. Your statement about "trampoline mini-interpreters often found in CPS implementations" is an attempt to introduce confusion between interpreters and the software emulation of tail call elimination. If you cannot give any concrete examples then you are just projecting confusion. – J D Jan 04 '12 at 09:50
  • it was not me who introduced the term "mini-interpreter" first. There is already a confusion, so please do not blame me for spreading it. Just accept the fact - there is no such a thing as a strict definition of an interpreter, neither in the industry nor in the academic CS. – SK-logic Jan 04 '12 at 10:20
  • "it was not me who introduced the term". Then who did? "There is already a confusion". People misuse terminology. "Just accept the fact". I do not accept that the difference between interpreters and compilers is "blurred" or confusing as you claim. "there is no such a thing as a *strict* definition of an interpreter". What do you intend this new "strict" qualifier you have introduced to mean? – J D Jan 04 '12 at 13:10
2

When you say that JavaScript is "dynamic", you usually mean "dynamically typed", which has nothing to do with the fact that it is usually implemented as an interpreted language and not compiled. The opposite of "dynamically typed" is "statically typed". Note that this is a different property then the one being described by "weakly typed" and "strongly typed". Both properties have nothing to do with interpreters vs. compilers, other then a tendency of scripting languages, which are almost always interpreted, to be dynamically typed.

A compiler is obviously (well, actually, the question is exactly about a compiler that is acting as an interpreter, but lets go with this for the sake of argument) not an interpreter, so if you compile some source code into an object file and execute it, you'd think that it is obviously not interpreted. But as it turns out, this is not a very clearly defined line. If you consider emulators to be interpreters, then you can interpret any executable, no matter what language it started out as. There's also binary translation and JIT compilers with their bytecode that muddy an already confused issue. But note that the confusion here is completely semantic, the solution is probably just an updated set of definitions.

Conversely, you can "compile" any interpreted language by recording what instructions the interpreter does when interpreting a program and playing it back as the compiled program. This is no exactly compilation, and it won't be any more efficient than the interpreter, but the point is that being interpreted is not an intrinsic quality of the language.

And so, languages that are traditionally compiled can and are sometimes implemented as interpreted languages. There are even interpreters for C out there. I believe this answers your question. I think the point being made about F# is that even though it is interactive, it's not an actual interpreter according to the strictest definition. This is because it compiles the bits of code and then runs them. This does not mean that a strict interpreter for F# could not be written due to some property of the language.

cha0site
  • 10,517
  • 3
  • 33
  • 51
  • by the way, this is most definitely semantics. But they're important semantics, and engineers should take care to be precise with their words. – cha0site Dec 30 '11 at 15:45
  • 1
    Speaking of which, why are you talking about compiled/interpreted languages as if it's an intrinsic property of the language and stating "Compiled languages can not be interpreted in any meaningful sense" despite showing (contrary) insight in other parts of your answer? ;) –  Dec 30 '11 at 15:54
  • You're right, this is confusing in that context. I *am* speaking of the implementation of the language in this paragraph. That is, if the language is implemented using a compiler, then it can not be interpreted - that is an oxymoron. Can you suggest better wording here? – cha0site Dec 30 '11 at 16:15
  • 1
    I can see how you might argue that a program can't be both a compiler and an interpreter (though that's blurry as well, sometimes to-bytecode compiler and bytecode interperter live in the same code base and process). But "if the language is implemented using a compiler, then it can not be interpreted" reads "there's magic that makes interpreters stop working when there's a compiler for the language". At the very least, clarify that "it" is the implementation, not the language. –  Dec 30 '11 at 16:19
  • All right, I think this clarifies it quite a bit. I disagree with you on the bytecode compiler and interpreter being in the same process making them the same - a compiler and linker for example can live in the same process, but they're still distinct stages. Did I earn my upvote? =D – cha0site Dec 30 '11 at 23:21
2

Scholastic arguments aside, code executed by FSI runs without a noticeable performance degradation compared to code compiled by FSC to an executable. In this regard F# favorably compares to OCaml - see comment from Harrop on OCaml toplevels.

t0yv0
  • 4,714
  • 19
  • 36
  • That's because FSI uses FSC to compile to an executable :-) (Or more precisely, FSI calls the same compiler library routines that FSC calls.) – Jörg W Mittag Dec 31 '11 at 11:13
  • 1
    Compared to the default OCaml top-level, yes. Compared to JIT top-levels like `ocamlnat` and `ocamljit`, no. – J D Jan 01 '12 at 08:55
1

Looking at the interpreter Wikipedia article, we find:

An interpreter may be a program that...translates source code into some efficient intermediate representation (code) and immediately executes this.

...which applies to FSI.

cHao
  • 84,970
  • 20
  • 145
  • 172
Daniel
  • 47,404
  • 11
  • 101
  • 179