Question

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.

Était-ce utile?

La solution

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.

Autres conseils

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.

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.

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.

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top