Comment by joshuapants

11 years ago

Think of it as like the Java runtime environment, but not terrible.

You have two main pieces: the Common Language Runtime, which is the virtual machine (like the JVM) that executes the code. Then you have the library it comes with, which is fairly large compared to most languages.

edit: Added more context

> Think of it as like the Java runtime environment, but not terrible.

What's terrible about the JVM/JRE?

Many people complain about the language Java (conservative language, programmer culture of complexity...), or the web browser plugin for the JVM (security vulnerabilities, bad startup performance...), but I've generally heard good things about the JVM itself.

  • The JVM type system uses type erasure (which means that any generic type Blah<T> becomes Blah at runtime), so you can't instantiate types based on generics at runtime. In C# it is valid to do "T foo = new T();" and because of reified generics, this works. You can't overload functions based on their generic type ("Foo(List<int> ...) and Foo(List<string> ...)" on the JVM (the <...> bit gets erased!). This was done to preserve binary backward compatibility when generics were introduced in Java.

    The CLR supports user-defined value types whereas the JVM doesn't, it relies on a classical uniform data representation. Because value types are stack allocated, in C#, you will have less stress on the GC (because you can define stack-allocated value types), on the other hand, the JVM GC will be doing a lot more work. This is why you see "the JVM is heavily optimized" statements.

    Another downside of the JVM is that it has no native support for tail call optimization, this is not that major, but it is a bit silly for functional languages running on the JVM (Clojure). The Scala compiler is intelligent enough to do this by itself, but there's no native support on the VM itself, unlike on the CLR.

    Another point is that the CLR was designed as a true language-agnostic virtual machine, so developing new languages on it is easy. It is not hard to do that on the JVM, but more so than on the CLR.

    • Technically, JVM doesn't have a type system, last I checked. Which is why Java (the language) uses type erasure. CLR does have a type system, but this also makes certain things harder to implement which is why, i think, Scala stopped working on their CLR compiler.

      The JVM was also designed as a language agnostic VM, which is why they stabilized their bytecode specification early on. There are certain things you can do in bytecode which cannot be done in Java for instance.

      Your criticism on the lack of user-defined value-types is valid, which they are working on for JVM 10. This is agreeably late, but better late than never.

    • There were experiments done some years ago for automated stack allocation in the JVM, by Azul. They had actual hardware support for it, it was very interesting. Basically they stack allocated everything by default and then moved stuff onto the heap when required.

      What they found is that it didn't make a big difference to performance. The problem is that generational GCs make allocating short lived small objects very cheap, basically as cheap as stack allocation. The main difference is that with stack allocation you are (potentially) better exploiting the cpu cache, but whether this makes a noticeable difference depends a lot on complicated things. It's not as clear a win as you would imagine and eventually Azul stopped bothering with it.

      I'd still like to see more aggressive stack allocation in the JVM. However, I am not expecting it to be some kind of silver bullet.

      Re: generics. It's true that type erasure causes some annoying problems. Oddly though, it has a big advantage too - it allows other JVM languages more flexibility to experiment with different approaches to generics. For example Kotlin uses a different style of generics to regular Java. If the JVM enforced the Java semantics that innovation wouldn't be possible, or at least, not at all easy. And of course one reason the Java world has a larger library ecosystem than .NET is that the .NET designers kept breaking backwards compatibility whereas the Java guys didn't. That's the reason JVM generics works the way it does. So the tradeoffs are rather subtle.

      It's not quite true that the CLR was designed to be language agnostic and the JVM wasn't. The JVM was intended to be language agnostic right from day one. However Microsoft had to try and unify the worlds of Visual Basic, Java/C# and C++ which were all popular on Windows at the time, so they emphasised it more from the start. However VB.NET and C# are very similar languages with the bulk of the differences being down to syntax. In particular, VB.NET is not really the same language as classical VB at all (e.g. different handling of threads).

      These days the JVM has lots of very different languages running on it with quite acceptable performance. They've done a lot of work on making very dynamic languages fast, through things like invokedynamic and Graal/Truffle. That's because those languages are very popular. They've done less work on functional languages, but I'm sure stuff they would benefit from will come with time.

      The real benefit of value types, by the way, is control over memory layout and thus CPU cache usage. Java tends to lose benchmarks against C++ partly because C++ programs naturally lay out data in more cache friendly ways. Value types in the JVM/Java language are likely to make a big difference here, though it's hard to say exactly how much ahead of time.

One of the interesting things I'm waiting to see is if .NET gets good enough to become the "main" platform for compile to VM languages like Clojure. It can already compile to .NET, but it's significantly less used than the JVM version, despite .NET generally being easier to target.

  • People have been using the CLR like that for many languages for many years. Maybe you didn't hear about it because it was a Windows thing.

    .NET was good enough when it came out many years ago. It was just a closed one platform thing.

How does it compare to Swift/Xcode/Mac Native?

  • You've listed three very different things there.

    For Swift, compare it to C# (depends on personal preference)

    For XCode, compare it to Visual Studio (IMO, VS is light years ahead)

    For Mac Native, compare to the .NET runtime (IMO .NET is better but it's not as clear cut)

    • > For XCode, compare it to Visual Studio (IMO, VS is light years ahead)

      I agree. VS is the best IDE I've ever used by far.

      > For Mac Native, compare to the .NET runtime (IMO .NET is better but it's not as clear cut)

      The only thing I wish is that MS made it a bit easier to make .NET transparent for the user. Occasionally you need to install a version of the runtime when you install a new program, it'd be nice if that was all "built-in" and taken care of instead of adding another step to the installation.

      3 replies →