Rectangle 27 21

Nearly every language is "compiled" nowadays, if you count bytecode as being compiled. Even Emacs Lisp is compiled. Ruby was a special case because until recently, it wasn't compiled into bytecode.

I think you're right to question the utility of characterizing languages as "compiled" vs. "interpreted." One useful distinction, though, is whether the language creates machine code (e.g. x86 assembler) directly from user code. C, C++, many Lisps, and Java with JIT enabled do, but Ruby, Python, and Perl do not.

People who don't know better will call any language that has a separate manual compilation step "compiled" and ones that don't "interpreted."

"Java with JIT enabled...". Shouldn't that be Java with JIT DISabled since JIT'ing is compiling bytecode to machine code? Therefore if the compiler generates something to be JITted, it's not generating machine code

interpreter - Is Ruby really an interpreted language if all of its imp...

ruby interpreter interpreted-language compiled-language
Rectangle 27 35

The JVM (Java Virtual Machine) has an instruction set just like a real machine. The name given to this instruction set is Java Bytecode. It is described in the Java Virtual Machine Specification. Other languages are translated into a bytecode before execution, for example ruby and python. Java's bytecode is at a fairly low level while python's is much more high level.

Interpretation and JIT compilation are two different strategies for executing bytecode. Interpretation processes bytecodes one at a time making the changes to the virtual machine state that are encoded in each instruction. JIT compilation translates the bytecode into instructions native to the host platform that carry out equivalent operations.

Interpretation is generally quick to start but slow during execution, while JIT has more startup overhead but runs quicker afterwards. Modern JVMs use a combination of interpretation and JIT techniques to get the benefit of both. The bytecode is first interpreted while the JIT is translating it in the background. Once the JIT compilation is complete, the JVM switches to using that code instead of the interpreter. Sometimes JIT compilation can produce better results than the ahead-of-time compilation used for C and C++ because it is more dynamic. The JVM can keep track of how often code is called and what the typical paths through the code are and use this information to generate more efficient code while the program is running. The JVM can switch to this new code just like when it initially switches from the interpreter to the JIT code.

Just like there are other languages that compile to native code, like C, C++, Fortran; there are compilers for other languages that output JVM bytecode. One example is the scala language. I believe that groovy and jruby can also convert to java bytecode.

@ladiesMan217 that is, of course, up to the particular implementation; but I expect that modern JVMs run the JIT compiler in a parallel thread

@GeoffReedy, +1. Got a good explanation after a long search.

java - What are bytecodes and how does the JVM handle them - Stack Ove...

java jvm bytecode
Rectangle 27 35

The JVM (Java Virtual Machine) has an instruction set just like a real machine. The name given to this instruction set is Java Bytecode. It is described in the Java Virtual Machine Specification. Other languages are translated into a bytecode before execution, for example ruby and python. Java's bytecode is at a fairly low level while python's is much more high level.

Interpretation and JIT compilation are two different strategies for executing bytecode. Interpretation processes bytecodes one at a time making the changes to the virtual machine state that are encoded in each instruction. JIT compilation translates the bytecode into instructions native to the host platform that carry out equivalent operations.

Interpretation is generally quick to start but slow during execution, while JIT has more startup overhead but runs quicker afterwards. Modern JVMs use a combination of interpretation and JIT techniques to get the benefit of both. The bytecode is first interpreted while the JIT is translating it in the background. Once the JIT compilation is complete, the JVM switches to using that code instead of the interpreter. Sometimes JIT compilation can produce better results than the ahead-of-time compilation used for C and C++ because it is more dynamic. The JVM can keep track of how often code is called and what the typical paths through the code are and use this information to generate more efficient code while the program is running. The JVM can switch to this new code just like when it initially switches from the interpreter to the JIT code.

Just like there are other languages that compile to native code, like C, C++, Fortran; there are compilers for other languages that output JVM bytecode. One example is the scala language. I believe that groovy and jruby can also convert to java bytecode.

@ladiesMan217 that is, of course, up to the particular implementation; but I expect that modern JVMs run the JIT compiler in a parallel thread

@GeoffReedy, +1. Got a good explanation after a long search.

java - What are bytecodes and how does the JVM handle them - Stack Ove...

java jvm bytecode
Rectangle 27 3

You can run Ruby programs interactively using irb, the Interactive Ruby Shell. While it may generate intermediate bytecode, it's certainly not a "compiler" in the traditional sense.

interpreter - Is Ruby really an interpreted language if all of its imp...

ruby interpreter interpreted-language compiled-language
Rectangle 27 136

PHP is compiled into bytecode, which is then interpreted on top of something resembling a VM. Many other scripting languages follow the same general process, including Perl and Ruby. It's not really a traditional interpreted language like, say, BASIC.

There would be no effective speed increase if you attempted to "minify" the source. You would get a major increase by using a bytecode cache like APC.

Facebook introduced a compiler named HipHop that transforms PHP source into C++ code. Rasmus Lerdorf, one of the big PHP guys did a presentation for Digg earlier this year that covers the performance improvements given by HipHop. In short, it's not too much faster than optimizing code and using a bytecode cache. HipHop is overkill for the majority of users.

Facebook also recently unveiled HHVM, a new virtual machine based on their work making HipHop. It's still rather new and it's not clear if it will provide a major performance boost to the general public.

Just to make sure it's stated expressly, please read that presentation in full. It points out numerous ways to benchmark and profile code and identify bottlenecks using tools like xdebug and xhprof, also from Facebook.

Note that the whole bytecode/vm thing doesn't actually buy you anything without an external(!) bytecode cache. I don't get why PHP keeps throwing the bytecode away by default...

I imagine that it's a shared hosting issue. APC is included in PHP by default as of the old 6.0-based trunk. I'm not sure if we'll see it by default in 5.4 or whatever the new trunk ends up being called...

Thanks very much for the info. Unfortunately I don't have deep control of my server (it's rented). Is it likely web hosts use APC?

Most shared hosting providers do not use APC. You should look into a Virtual Private Server so that you can control the configuration. VPSes are often more expensive than normal shared hosting, but far less expensive than a real dedicated server. Popular VPS providers include Slicehost and Linode. Don't forget that you should be benchmarking and profiling your code first!

minify - Is there a point to minifying PHP? - Stack Overflow

php minify
Rectangle 27 3

The term 'scripting language' is very broad, and it can include both interpreted and compiled languages. Ruby in particular, might compiled or interpreted depending on what particular implementation we're using - for instance, JRuby gets compiled to bytecode, whereas CRuby (Ruby's reference implementation) is interpreted

definition - Is Ruby a scripting language or an interpreted language? ...

ruby definition scripting-language interpreted-language compiled-language
Rectangle 27 19

Yes, Ruby's still an interpreted language, or more precisely, Matz's Ruby Interpreter (MRI), which is what people usually talk about when they talk about Ruby, is still an interpreter. The compilation step is simply there to reduce the code to something that's faster to execute than interpreting and reinterpreting the same code time after time.

interpreter - Is Ruby really an interpreted language if all of its imp...

ruby interpreter interpreted-language compiled-language
Rectangle 27 3

It's a bytecode interpreter called YARV, written by Sasada Koichi.

puts RubyVM::InstructionSequence.compile("1+1").disasm
== disasm: #<ISeq:<compiled>@<compiled>>================================
0000 trace            1                                               (   1)
0002 putobject_OP_INT2FIX_O_1_C_
0003 putobject_OP_INT2FIX_O_1_C_
0004 opt_plus         <callinfo!mid:+, argc:1, ARGS_SIMPLE>, <callcache>
0007 leave

While MRI doesn't have a JIT yet, there's the Ruby+OMR project, that's trying to add a JIT compiler based on Eclipse OMR:

Wow! Really interesting! I didn't know it's available from inside the language itself.

I still don't understand what's the difference between a bytecode interpreter and a JIT compiler though. Just asked a question about it in Software Engineering. Thanks for your answer!

@user6245072: the key difference is simply this: an interpreter executes the program. A compiler translates the program from one language to another. AOT vs. JIT refers to when the compilation takes place: ahead-of-time is before runtime, just-in-time is at runtime.

implementation - What kind of interpreter is the Ruby MRI? - Stack Ove...

ruby implementation interpreter
Rectangle 27 8

A subtle question indeed... It used to be that "interpreted" languages were parsed and transformed into an intermediate form which was faster to execute, but the "machine" executing them was a pretty language specific program. "Compiled" languages were translated instead into the machine code instructions supported by the computer on which it was run. An early distinction was very basic--static vs. dynamic scope. In a statically typed language, a variable reference could pretty much be resolved to a memory address in a few machine instructions--you knew exactly where in the calling frame the variable referred. In dynamically typed languages you had to search (up an A-list or up a calling frame) for the reference. With the advent of object oriented programming, the non-immediate nature of a reference expanded to many more concepts--classes(types), methods(functions),even syntactical interpretation (embedded DSLs like regex).

The distinction, in fact, going back to maybe the late 70's was not so much between compiled and interpreted languages, but whether they were run in a compiled or interpreted environment. For example, Pascal (the first high-level language I studied) ran at UC Berkeley first on Bill Joy's pxp interpreter, and later on the compiler he wrote pcc. Same language, available in both compiled and interpreted environments.

Some languages are more dynamic than others, the meaning of something--a type, a method, a variable--is dependent on the run-time environment. This means that compiled or not there is substantial run-time mechanism associated with executing a program. Forth, Smalltalk, NeWs, Lisp, all were examples of this. Initially, these languages required so much mechanism to execute (versus a C or a Fortran) that they were a natural for interpretation.

Even before Java, there were attempts to speed up execution of complex, dynamic languages with tricks, techniques which became threaded compilation, just-in-time compilation, and so on.

I think it was Java, though, which was the first wide-spread language that really muddied the compiler/interpreter gap, ironically not so that it would run faster (though, that too) but so that it would run everywhere. By defining their own machine language and "machine" the java bytecode and VM, Java attempted to become a language compiled into something close to any basic machine, but not actually any real machine.

Modern languages marry all these innovations. Some have the dynamic, open-ended, you-don't-know-what-you-get-until-runtime nature of traditional "interpreted languages (ruby, lisp, smalltalk, python, perl(!)), some try to have the rigor of specification allowing deep type-based static error detection of traditional compiled languages (java, scala). All compile to actual machine-independent representations (JVM) to get write once-run anywhere semantics.

So, compiled vs. interpreted? Best of both, I'd say. All the code's around in source (with documentation), change anything and the effect is immediate, simple operations run almost as fast as the hardware can do them, complex ones are supported and fast enough, hardware and memory models are consistent across platforms.

The bigger polemic in languages today is probably whether they are statically or dynamically typed, which is to say not how fast will they run, but will the errors be found by the compiler beforehand (at the cost of the programmer having to specify pretty complex typing information) or will the errors come up in testing and production.

interpreter - Is Ruby really an interpreted language if all of its imp...

ruby interpreter interpreted-language compiled-language
Rectangle 27 9

Yes, the mythical "somebody" can replace the implementation of MD5 with something insecure. But in order to do that, the mythical somebody must actually be able to get his code into the Ruby process. And if he can do that, then he presumably could also inject his code into a Java process and e.g. rewrite the bytecode for the MD5 operation. Or just intercept the keypresses and not actually bother with fiddling with the cryptography code at all.

One of the typical concerns is: I'm writing this awesome library, which is supposed to be used like so:

require 'awesome'
# Do something awesome.

But what if someone uses it like so:

require 'evil_cracker_lib_from_russian_pr0n_site'
# Overrides crypto functions and sends all data to mafia
require 'awesome'
# Now everything is insecure because awesome lib uses 
# cracker lib instead of builtin

And the simple solution is: don't do that! Educate your users that they shouldn't run untrusted code they downloaded from obscure sources in their security critical applications. And if they do, they probably deserve it.

To come back to your Java example: it's true that in Java you can make your crypto code private and final and what not. However, someone can still replace your crypto implementation! In fact, someone actually did: many open-source Java implementations use OpenSSL to implement their cryptographic routines. And, as you probably know, Debian shipped with a broken, insecure version of OpenSSL for years. So, all Java programs running on Debian for the past couple of years actually did run with insecure crypto!

security - How can I program defensively in Ruby? - Stack Overflow

ruby security defensive-programming
Rectangle 27 3

A compiled language is generally compiled into machine code, as opposed to just byte code. Some byte code generators can actually further compile the byte code into machine code though.

Byte code itself is just an intermediate step between the literal code written by the user and the virtual machine, it still needs to be interpreted by the virtual machine though (as it's done with Java in a JVM and PHP with an opcode cache).

interpreter - Is Ruby really an interpreted language if all of its imp...

ruby interpreter interpreted-language compiled-language
Rectangle 27 4

Java uses bytecode because two of its initial design goals were portability and compactness. Those both came from the initial vision of a language for embedded devices, where fragments of code could be downloaded on the fly.

Python, Ruby, Smalltalk, javascript, awk and so on use bytecode because writing a native compiler is a lot of work, but a textual interpreter is too slow - bytecode hits a sweet spot of being fairly easy to write, but also satisfactorily quick to run.

I have no idea why the Microsoft languages use bytecode, since for them, neither portability nor compactness is a big deal. A lot of the thinking behind the CLR came out of computer scientists in Cambridge, so i imagine considerations like ease of program analysis and verification were involved.

Note that as well as C++ and Objective C, Eiffel, Ada 9X, Vala and Go are OO languages (of varying vintage) that are compiled straight to native code.

All in all, i'd say that OO and bytecode do not go hand in hand. Rather, we have a coincidental convergence of several streams of development: the traditional bytecoded interpreters of scripting languages like Python and Ruby, the mad Gosling masterplan of Java, and whatever it is Microsoft's motives are.

Microsoft's .Net runs on non-PC architectures as well - Xbox360 and Windows Mobile 7, hence portability.

oop - Why do almost all OO languages compile to bytecode? - Stack Over...

oop compiler-construction programming-languages bytecode
Rectangle 27 71

I think either language will be fast enough for you. When comparing Python and Java, it seems a bit unreasonable to blame the language for the speed difference. Java is compiled JIT (except on mobile devices*) whereas Python is interpreted. Just because both use a bytecode does not mean the implementations will have even remotely comparable performance. But both Scala and Clojure are JVM languages so they should have similar performance.

Scala has a few implementation advantages over Clojure and I would expect somewhat higher performance. Although Scala's static typing would normally translate into a speed advantage over Clojure's duck typing, Clojure does support type hinting which can speed up code considerably. Possibly, ordinary Scala is faster than ordinary Clojure, but you only need to optimize the bottlenecks. Most of a program's run time is generated by a small amount of the actual code.

Regarding interop w/ Java, Scala is closer to Java but I'm sure both languages interoperate well. In Programming Clojure Stuart Halloway writes: "[you can access] anything you could reach from Java code.".

And since Scala author Martin Odersky wrote Sun's Java compiler, I kinda think no balls have been dropped on the Scala side, either. :-)

You would be hard-pressed to pick two better languages, though I like Ruby also. Why are you worried about which one to try? Why not try them both? Scala is more likely to be "the next Java", while it's hard to imagine that Lisp will finally take off after not doing so for over 50 years. But it's clear that Lisp is on its own unique level of abstraction, and Clojure is fairly simple, so Scala + Clojure won't be that much harder than just (the rather complex) Scala and I'm sure you will be glad you did it.

* dalvik (android's JVM) got a JIT compiler in 2.2 version in 2010

Huh. Well, thanks for all of the insights. At first, I was in the mode where I wanted to just pick one and run with it. But for some reason, it didn't occur to me that I could just use both and have them inter-operate. So, perhaps I'll pick both and do a fast-walk with them :-)

And I'd like to add that I do have a bit of a "soft spot" for LISP so the fact that Clojure suffers from parethesitis isn't enough to scare me away.

It's not always true that a language written in the JVM will perform at top speed. The original JRuby had abysmal performance because it was an interpreter that was compiled to the JVM, not the source code. The language, also, can be to blame. Statically typed languages are often easier to optimize than dynamic languages, etc.

-1 "both Scala and Clojure are JVM languages so they should have similar performance" makes absolutely no sense. Dynamic languages that need to stay interoperable with a static languages like Java are always much slower (overloading comes at a huge cost, type hinting doesn't solve all the problems, etc.)

@julkiewicz - it is simply not true that dynamic languages are always much slower. It depends on whether your compiler can do a decent job of optimising the code in question. For example, in Clojure you can do arithmetic with Java primitives that exactly matches Java performance. Likewise, calling a method on a type-hinted Java object is as fast as a Java object method call. The Clojure compiler essentially produces the same bytecode as javac would for equivalent Java code.

On Performance and Java Interoperability: Clojure vs. Scala - Stack Ov...

java performance scala clojure jvm
Rectangle 27 71

I think either language will be fast enough for you. When comparing Python and Java, it seems a bit unreasonable to blame the language for the speed difference. Java is compiled JIT (except on mobile devices*) whereas Python is interpreted. Just because both use a bytecode does not mean the implementations will have even remotely comparable performance. But both Scala and Clojure are JVM languages so they should have similar performance.

Scala has a few implementation advantages over Clojure and I would expect somewhat higher performance. Although Scala's static typing would normally translate into a speed advantage over Clojure's duck typing, Clojure does support type hinting which can speed up code considerably. Possibly, ordinary Scala is faster than ordinary Clojure, but you only need to optimize the bottlenecks. Most of a program's run time is generated by a small amount of the actual code.

Regarding interop w/ Java, Scala is closer to Java but I'm sure both languages interoperate well. In Programming Clojure Stuart Halloway writes: "[you can access] anything you could reach from Java code.".

And since Scala author Martin Odersky wrote Sun's Java compiler, I kinda think no balls have been dropped on the Scala side, either. :-)

You would be hard-pressed to pick two better languages, though I like Ruby also. Why are you worried about which one to try? Why not try them both? Scala is more likely to be "the next Java", while it's hard to imagine that Lisp will finally take off after not doing so for over 50 years. But it's clear that Lisp is on its own unique level of abstraction, and Clojure is fairly simple, so Scala + Clojure won't be that much harder than just (the rather complex) Scala and I'm sure you will be glad you did it.

* dalvik (android's JVM) got a JIT compiler in 2.2 version in 2010

Huh. Well, thanks for all of the insights. At first, I was in the mode where I wanted to just pick one and run with it. But for some reason, it didn't occur to me that I could just use both and have them inter-operate. So, perhaps I'll pick both and do a fast-walk with them :-)

And I'd like to add that I do have a bit of a "soft spot" for LISP so the fact that Clojure suffers from parethesitis isn't enough to scare me away.

It's not always true that a language written in the JVM will perform at top speed. The original JRuby had abysmal performance because it was an interpreter that was compiled to the JVM, not the source code. The language, also, can be to blame. Statically typed languages are often easier to optimize than dynamic languages, etc.

-1 "both Scala and Clojure are JVM languages so they should have similar performance" makes absolutely no sense. Dynamic languages that need to stay interoperable with a static languages like Java are always much slower (overloading comes at a huge cost, type hinting doesn't solve all the problems, etc.)

@julkiewicz - it is simply not true that dynamic languages are always much slower. It depends on whether your compiler can do a decent job of optimising the code in question. For example, in Clojure you can do arithmetic with Java primitives that exactly matches Java performance. Likewise, calling a method on a type-hinted Java object is as fast as a Java object method call. The Clojure compiler essentially produces the same bytecode as javac would for equivalent Java code.

On Performance and Java Interoperability: Clojure vs. Scala - Stack Ov...

java performance scala clojure jvm
Rectangle 27 2

In case of Rubinius, the VM is written in C++ and deals with all the lowlevel (operating system related) stuff and base operations. The VM has it's own bytecode format (like the JVM has its own as well) and when Rubinius is started it starts the VM which executes the bytecode. Most of Rubinius' standard library (which is part of Ruby the language) is implemented in Ruby however, compared to C (MRI) or Java (JRuby). Also, the Rubinius bytecode compiler is also written in Ruby. So yeah, at some point early on in the beginning they had to use the standard Ruby interpreter (MRI) to bootstrap Rubinius. But this shouldn't be the case anymore (although I'm not sure if you still might need it since its build-system uses rake).

ruby - How can a language be interpreted by itself (like Rubinius)? - ...

ruby compiler-construction language-design rubinius self-interpreter
Rectangle 27 1

Bytecode is significantly more flexible medium than machine code. First, it provides the basis for platform portability without the need for a compiler or shipping source code. So a developer can distribute a single version of the application without needing to give up the source, require complex developer tools, or anticipate potential target platforms. While the later is not always practical it does happen. Especially with developer libraries say I distribute a library that I've only tested on Windows, but someone else uses it on Linux or Android. It happens quite frequently actually, and most of the time it works as expected.

Byte code is also generally more optimized that an interpreter because it's closer to machine instructions therefore faster to translate to machine instructions. Not all OO languages are compiled. Ruby, Python, and even Javascript are interpreted so they aren't compiled to anything so the ruby interpreter has to take a very flexible language and turn that into instructions, but that flexibility comes at a price paid an runtime: parse text, generate AST, translate AST to machine code, etc. It's also easy to do optimizations like JIT where byte code is translated to machine code directly, and even gives the possibility for creating optimizations for specific hardware.

Finally, just because one language compiles to bytecode doesn't preclude other languages taking advantage of of that byte code. Now any optimization using that byte code can be applied to these other languages that might know how to translate themselves to that byte code. That makes the byte code a very important layer for reusability for other languages.

OO and byte code compilation goes back to the 70s with Smalltalk, and I'm sure someone will say LISP as early as the 50s/60s. But, it really wasn't until the 90s that it started to really be used in production systems on a large scale.

Native compilation sounds like the optimal path, and probably why our industry spent 20 years or more thinking that was THE ANSWER to all our problems, but the last 15 years we've seen byte code compilation take stage and it's been a significant advantage over what we did before. Looking back we realize how much time wasted natively compiling everything mostly by hand.

LUA compiles to bytecode, and runs on a VM, but is just as flexible as Javascript, as far as program structuring goes. I believe (at least some) LISP implementations do this, as well.

Python is compiled. This happens when you run the script, if it didn't happen earlier.

hmm, i take issue with juxtaposing byte code vs "interpeter" because byte code (AKA p-code) is executed by an interpreter - even if you call that a VM. You mean "pure interpretation" there. Also, Javascript is not necessarily only pure interpreter - Google Chrome compiles JS to native code (lookup V8 Javascript engine). Ruby has a bytecode interpreter nowadays too, the so called YARV (vs previous MRI).

There are key difference between byte code and interpreters. Interpreters have to parse source code and build ASTs in order to interpret and validate code. Bytecode does not. Even interpreting the cached AST performs far worse than byte code. Calling byte code an interpreter is vastly under estimating the performance of byte code vs. interpreters. While most languages are now byte code optimized they did not start out that way. Early versions of Javascript, LUA, Python, and Perl did not start out with byte code. Ruby only got YARV in the last two years of it's almost 20 year life.

oop - Why do almost all OO languages compile to bytecode? - Stack Over...

oop compiler-construction programming-languages bytecode
Rectangle 27 35

The Low Level Virtual Machine (LLVM) is a compiler infrastructure, written in C++, which is designed for compile-time, link-time, run-time, and "idle-time" optimization of programs written in arbitrary programming languages. Originally implemented for C/C++, the language-independent design (and the success) of LLVM has since spawned a wide variety of front-ends, including Objective C, Fortran, Ada, Haskell, Java bytecode, Python, Ruby, ActionScript, GLSL, and others.Read this for more explanation Also check out Unladen Swallow

What exactly is LLVM? - Stack Overflow

llvm
Rectangle 27 0

A subtle question indeed... It used to be that "interpreted" languages were parsed and transformed into an intermediate form which was faster to execute, but the "machine" executing them was a pretty language specific program. "Compiled" languages were translated instead into the machine code instructions supported by the computer on which it was run. An early distinction was very basic--static vs. dynamic scope. In a statically typed language, a variable reference could pretty much be resolved to a memory address in a few machine instructions--you knew exactly where in the calling frame the variable referred. In dynamically typed languages you had to search (up an A-list or up a calling frame) for the reference. With the advent of object oriented programming, the non-immediate nature of a reference expanded to many more concepts--classes(types), methods(functions),even syntactical interpretation (embedded DSLs like regex).

The distinction, in fact, going back to maybe the late 70's was not so much between compiled and interpreted languages, but whether they were run in a compiled or interpreted environment. For example, Pascal (the first high-level language I studied) ran at UC Berkeley first on Bill Joy's pxp interpreter, and later on the compiler he wrote pcc. Same language, available in both compiled and interpreted environments.

Some languages are more dynamic than others, the meaning of something--a type, a method, a variable--is dependent on the run-time environment. This means that compiled or not there is substantial run-time mechanism associated with executing a program. Forth, Smalltalk, NeWs, Lisp, all were examples of this. Initially, these languages required so much mechanism to execute (versus a C or a Fortran) that they were a natural for interpretation.

Even before Java, there were attempts to speed up execution of complex, dynamic languages with tricks, techniques which became threaded compilation, just-in-time compilation, and so on.

I think it was Java, though, which was the first wide-spread language that really muddied the compiler/interpreter gap, ironically not so that it would run faster (though, that too) but so that it would run everywhere. By defining their own machine language and "machine" the java bytecode and VM, Java attempted to become a language compiled into something close to any basic machine, but not actually any real machine.

Modern languages marry all these innovations. Some have the dynamic, open-ended, you-don't-know-what-you-get-until-runtime nature of traditional "interpreted languages (ruby, lisp, smalltalk, python, perl(!)), some try to have the rigor of specification allowing deep type-based static error detection of traditional compiled languages (java, scala). All compile to actual machine-independent representations (JVM) to get write once-run anywhere semantics.

So, compiled vs. interpreted? Best of both, I'd say. All the code's around in source (with documentation), change anything and the effect is immediate, simple operations run almost as fast as the hardware can do them, complex ones are supported and fast enough, hardware and memory models are consistent across platforms.

The bigger polemic in languages today is probably whether they are statically or dynamically typed, which is to say not how fast will they run, but will the errors be found by the compiler beforehand (at the cost of the programmer having to specify pretty complex typing information) or will the errors come up in testing and production.

Is Ruby really an interpreted language if all of its implementations a...

ruby implementation interpreter interpreted-language compiled-language
Rectangle 27 0

A compiled language is generally compiled into machine code, as opposed to just byte code. Some byte code generators can actually further compile the byte code into machine code though.

Byte code itself is just an intermediate step between the literal code written by the user and the virtual machine, it still needs to be interpreted by the virtual machine though (as it's done with Java in a JVM and PHP with an opcode cache).

Is Ruby really an interpreted language if all of its implementations a...

ruby implementation interpreter interpreted-language compiled-language
Rectangle 27 0

I haven't seen any work in this direction from reading ruby-core (I am a committer). Compilation to bytecode doesn't take very long in ruby. Compared to the runtime of most ruby programs it hasn't yet made sense to persist compiled bytecode to disk.

Compiling Ruby 2.1 to bytecode - Stack Overflow

ruby ruby-2.0 ruby-2.1