views:

140

answers:

5

Interpreted languages are usually more high-level and therefore have features as dynamic typing (including creating new variables dynamically without declaration), the infamous eval and many many other features that make a programmer's life easier - but why can't compiled languages have these as well?

I don't mean languages like Java that run on a VM, but those that compile to binary like C(++).

I'm not going to make a list now but if you are going to ask which features I mean, please look into what PHP, Python, Ruby etc. have to offer.

  • Which common features of interpreted languages can't/don't/do exist in compiled languages? Why?
A: 

Initially, one of the largest benefits of interpreted languages was debugging. That way you can get incredibly accurate and detailed information when looking for the reason a program isn't working. However, most compilers have become advanced enough that that is not too big of a deal any more.

The other main benefit (in my opinion anyway), is that with interpreted languages, you don't have to wait for eternity for your project to compile to test it out.

Leif Andersen
Doesn't address the question.
anon
A: 

You couldn't plausibly do eval, for example, for reasons I'd have thought were pretty obvious: exactly how would you implement it? Make the runtime contain a full copy of the compiler? Every time you wanted to evaluate a string (keeping in mind that each time it could be different!) you'd save the string to a file, run the compiler on it to make a DLL/shared-lib, then load that DLL/shared-lib and call your code? You can't see why this might be a wee bit impractical? ;)

You can find this kind of thing in dynamic languages all over the place that you can't do with static code short of basically running an interpreter, in effect, behind the scenes.

JUST MY correct OPINION
I think you can do eval. And you said how already: Make the runtime contain a full copy of the compiler. That is how interpreted languages do it, right? Calling eval is nothing other than calling the interpreter. So, in a compiled languages it should be nothing other than calling the compiler. In .NET you can emit IL (some sort of assembly/bytecode) directly with having to "save string to file, ... load DLL". It's not that uncommon. Even though not many use something exactly like "eval", it's not that impractical.
Martinho Fernandes
A real-world example: boo is compiled and has an interpreter. I would argue there's an eval somewhere in the bowels of the interpreter. Also, what Dario said.
Martinho Fernandes
I've seen a demo of REPL behavior for C#. So, eval can be done with compiled languages.
John Fisher
@John Fisher: that was probably Anders Hejlsberg presentation in the PDC'08 (http://channel9.msdn.com/pdc2008/TL16/). At the time he was using a prototype of a C# "beyond 4.0" language.
Martinho Fernandes
Real-world example: Common Lisp. Good implementations are compiled.
David Thornley
The point of eval is not to compile and run code, but to compile and run it in the **current scope**. See `x = 41; eval("print(++x)");` should print 42 as well as increment our current `x`. There is no way of even coming close to this in C#.
Dario
@Dario: yes, that a difficulty, mainly because `x` as we know it might not even exist after the compiler does its optimizations. It doesn't mean some other language (or a special C# compiler) can't keep that kind of metadata around... But at that point we'll be pushing the boundaries of what compiled/interpreted means. The best I've seen so far in the .NET world is boo (http://docs.codehaus.org/display/BOO/Scripting+with+the+Boo.Lang.Interpreter+API). You have to be explicit about what is or isn't in scope though :(
Martinho Fernandes
Another real-world example, but on the other direction: Python can be compiled to some form of bytecode.
Martinho Fernandes
@Dario, I've actually written C# code which conquers the significant barriers you brought up. So I know that there is not only a way of coming close, but a way of actually achieving what you said cannot be done with C#.
John Fisher
+3  A: 

Whether source code is compiled - to native binaries, some kind of intermediate language (Java Bytecode/IL) - or interpreted is absolutely no trait of the language. It's just a question of the implementation.

You can actually have both compilers and interpreters for the same language like

  • Haskell: GHC <-> GHCI
  • C: gcc <-> ch
  • VB6: VS IDE <-> VB6 compiler

Certain language features like eval or dynamic typing may suggest a distinction between so called "dynamic languages" and static ones, but how this is run can never be the primary question.

Dario
+1. When you run compiled Java, you're actually interpreting Java bytecode. I don't see a lot of differences, other than the fact that Ruby is human-readable and Java bytecode isn't. That's not relevant. If you think about it, we can dismiss the "artificial" distinction between compiled and interpreted, make the question moot, and think about the dynamic/static divide instead.
Martinho Fernandes
@Martinho: Exactly. One could even call a standalone interpreter with the source included a compiler ;)
Dario
A: 

Continuing on from Dario - I think you are really asking why a compiled program can't evaluate statements at runtime (e.g. eval). Here's some reasons I can think of:

  • The full compiler would have to be distributed with the program (or be part of the program)
  • For an eval function to have access to type information and symbols (such as variable names and function names) in the environment it was used the original program would have to be compiled with those symbols accessible (compiled languages usually remove these symbols at compile time).

Edit: As noted neither of these reasons make it impossible for a language/compiler to be able to evaluate code at runtime, but they are definitely things that need to be taken into consideration when developing a compiler or when designing a language.

CiscoIPPhone
Common Lisp has `eval` at runtime, and industrial-strength implementations are compiled.
David Thornley
I'm not trying to say it's impossible for compiled programs to have an eval, I'm just giving some reasons why many languages don't have an eval. I'll update my answer to make this clear.
CiscoIPPhone
The compiler can be distributed with the runtime, just like interpreters are not part of interpreted programs. Also, modern platforms like .NET and Java carry type information as metadata in the compiled units (assembly in .NET, JAR in Java). Only local variable names are stripped, because even local variables themselves can be entirely removed by optimizations.
Martinho Fernandes
Yep - Concerning `eval`, see http://stackoverflow.com/questions/2261628/c-how-to-access-locals-through-stack-trace-mimicking-dynamic-scope/2261718#2261718: Might be interesting
Dario
A: 

Maybe the question is not about interpreted/compiled languages (compile is ambiguous anyway) but about languages that do/don't carry their own compiler around with them? For instance we've said C++ could do eval with a handy compiler floating around in the app, and reflection presumably is similar in some ways.

John
There are C compiler libraries that are designed for precisely that purpose: so you can embed a C compiler into your application for scripting using C. libtcc is one such example.
Jörg W Mittag