5
$\begingroup$

Most interpreted languages use a virtual machine internally, to speed up performance. This is achieved by having an internal compiler compile the code (usually with minimal optimization and maximum speed) and send it over to a VM to be executed. Usually the bytecode goes directly from the compiler to the VM to be executed, but some languages like Python cache the bytecode for repeated runs. Most famously, Java distinctly separates the compilation and execution phases, requiring you to compile and run separately.

Some languages, instead of using their own internal virtual machine, compile to target another virtual machine instead. Again, the Java Virtual Machine is the most famous example of this, with the most notable languages targeting it being Kotlin, Scala, Groovy, and Clojure. JVM is not the only one, with several languages compiling to Lua bytecode, and I've heard of a few compiling to Python bytecode.1

Languages targeting other language's VMs have to deal with ABI instability, lack of documentation (with the previous two points again not holding true for the JVM), and the fact that VMs are typically tailored to the source language. Given all that, why would you want to target another language's VM?

1Technically, the CLR and LLVM could fit here too, but they were designed for use with multiple languages

$\endgroup$
15
  • 4
    $\begingroup$ I feel like a lot of the same reasons apply for using an existing backend (e.g. LLVM) for a compiled language. $\endgroup$
    – Bbrk24
    Commented Jul 21, 2023 at 14:23
  • 2
    $\begingroup$ This is tagged "history", but nothing in the body or title of the question suggests anything related to history. What are you intending this to be? $\endgroup$
    – Michael Homer
    Commented Jul 21, 2023 at 20:36
  • 3
    $\begingroup$ I think this question is too broad. The reasons to compile to a VM specifically designed to supports lots of different languages (like the JVM/CLR) are totally different from the reasons to target a VM that is essentially just a runtime for a specific language. $\endgroup$
    – Alexis King
    Commented Jul 21, 2023 at 22:37
  • 3
    $\begingroup$ @Seggan-OnStrike Ok, but it doesn't. actually... ask that anywhere, and as you can see none of the answers have read that into it either. I see the tag is there, but it doesn't currently describe the question itself. $\endgroup$
    – Michael Homer
    Commented Jul 22, 2023 at 2:37
  • 2
    $\begingroup$ "Given all that, why would you want to target another language's VM?" - what alternative are we contrasting this with? Compiling to native code? Creating a new VM specific to the language? Something else? $\endgroup$ Commented Jul 22, 2023 at 6:24

6 Answers 6

11
$\begingroup$

It is often easier to compile to a vm's bytecode than it is to compile to native machine code. And the VM is likely to have good JIT optimization. This means that you don't have to deal with optimization in the compiler.

Targeting a VM also means that you have a compile once, run everywhere option assuming there is a VM implemented for each platform you intend to run it on. In other words the ABI tends to be consistent across different platforms but not necessarily across time.

$\endgroup$
8
$\begingroup$

One big one is that people are more likely to have that VM installed already. The thing with languages that compile to bytecodes is the user has to install the VM/runtime; if you piggyback off Java with its [googles] 5.5 billion devices, not only do you save the work of having to implement and optimize your own VM, you save the work of having to host and package it, and your users save the work of having to install it (or the disk space/time of having it installed automatically).

$\endgroup$
8
$\begingroup$

Interoperability

When targeting an existing VM, your language can now be mixed with all the existing languages that target that VM.

Libraries

All the existing libraries for these languages can also be reused.

Maybe you also get to reuse package managers for these libraries.

Tooling

You get to reuse any existing tooling that works at the VM bytecode level. For example, profilers, decompilers, debugggers, code injectors, analyzers...

$\endgroup$
8
$\begingroup$

Why re-invent the wheel?

To summarize many good points already addressed in detail in the other answers:

  1. A virtual machine (such as Java VM) exists, is often well-understood, and (possibly) well-documented.

  2. Compiling to a virtual machine is often simpler than compiling to a particular hardware architecture (most VMs are stack machines), and...

  3. The virtual machine will run on a large variety of actual processor architectures, operating systems, etc.

  4. The virtual machine will likely be a well-developed and well-tested piece of software, with good run-time (JIT) optimization, a built-in garbage collector, exception handling, and many other useful features.

  5. Interoperability with libraries written for the same VM is obviously a very welcome feature!

In short, VMs exist, they work well, they have many useful and well-developed features – so why not make good use of them? Why reinvent the wheel?

$\endgroup$
1
3
$\begingroup$

Other people have already said things like this, but I wanted to give some specific examples.

Kotlin targets the JVM, which means Kotlin can load Java jars (and vice versa). Apparently it's even easy to convert a Java codebase into Kotlin piecemeal because you can have both languages in the same project.

Powershell can load .NET DLLs, which makes it easy to write cmdlets in C# and use them in Powershell.

Jython is interesting. It's Python that runs in the JVM, which, again, enables interoperability between the two languages.

Because you get this increased interoperability, it also makes it easier for people to adopt your language. A Java shop is going to be a lot more willing to try Kotlin than a completely unrelated language. There are other ways to support transitioning from one language to another, but targeting the same VM can make a big difference.

$\endgroup$
-1
$\begingroup$

Well, the compiler for my programming language targets WebAssembly because WebAssembly is designed to be an extremely easy compilation target. And lack of documentation and ABI instability are not a problem for the WebAssembly virtual machine.

$\endgroup$

Not the answer you're looking for? Browse other questions tagged .