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
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)
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.
.NET Core is _not_ built-in to the OS, so apps can carry it within their package, meaning that there is never a need to add another step to the installation. This is a major goal of .NET Core.
.NET was good enough when it came out many years ago. It was just a closed one platform thing.
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 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.
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.
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.
Up until now however it has only ran on Windows which was its biggest "downside" Vs. Java which runs on many platforms.
How would .NET compare to Apple's native environment?
I guess the whole point is to write cross-platform code, but is the .NET environment that much better than Swift/Xcode?
I mean, Java never really caught on with the Mac user base.
Although there are some good bindings to cocoa to do so.
You said it all. The whole point is cross platform development.
People use Swift to develop apps for Apple products. Before Dot.net was made open source, people only used it to develop for Microsoft platforms.
The fact Dot.net is now crossplatform makes it possible for GNU/Linux and Mac users to consider it for development.
I am not going to make the same mistake twice and be tied down to a language (Objective-C) and private APIs (Cocoa, iOS, etc) which are useless outside of Apple's ivory tower.
I had always thought of C# and Mono as a potential cross-platform solution, but now that .NET is open-source and Microsoft are pushing it hard, even on Linux, it has become a viable one.
I suspect I am not the only Mac->iOS developer who is thinking along these lines.
But a cross-platform CLR opens up some possibilities even for desktop or CLI apps. The wealth of the .NET ecosystem is compelling.
Well, probably it is better if you have (say) a company full of people who know how to write C# but have never used Swift. And the whole write once run anywhere thing is nice (sure, native apps "feel" better, but if there are no native apps I'd rather have a Java version than nothing).
- The biggest relevant difference -- which he mentions -- is indeed value types, which are coming to Java,
- The CLR doesn't have coroutines. Yield/await are what's known as "stackless coroutines" and are, AFAIK, implemented at the language level (and besides, stackless coroutines are a far cry from coroutines, as the most powerful concept of coroutines is the stack). The JVM, OTOH, offers such sophisticated bytecode manipulation capabilities that full coroutines can be implemented as a library (e.g. Quasar).
- What he says of bytecode/package design bears absolutely no relevance to the quality -- or power -- of the VM. Those are just simple design tradeoffs with little effect on results.
Also, see my reply to math.
There's a larger variety of JVMs designed for a broader range of hardware, the most interesting to me being Azul and their GC tech.
But the CLR gives you some different tactical options. Value types and unsafe code let you do things that are far more expensive or awkward on the JVM. Writing a significant amount of functionality that does no heap allocation is more feasible on the CLR than JVM. Native interop is an order of magnitude easier. The CLR is generally much faster to start up; Java terminal apps don't suit interactive use. The library linking story is much more pleasant too, with a single dynamically linked executable referencing GAC-installed assemblies, rather than stringing together enormously long class paths.
True, although the most relevant difference is value types, which Java is getting, too. As to the rest, it's not about the number of features, but the quality of implementation. HotSpot's JIT and GCs are simply years ahead of the CLR, and HotSpot's next-gen JIT, Graal, is another tremendous leap forward.
> The CLR is generally much faster to start up
Compared to HotSpot, yes (but, like you said, there are many JVMs out there), although Java 9's JIT caching will change that.
> The library linking story is much more pleasant too, with a single dynamically linked executable referencing GAC-installed assemblies, rather than stringing together enormously long class paths.
This, too, is no longer the case in Java 9, but the difference in the other direction is much more relevant: the JVM's agent capabilities (both Java and native agents) are one of the things that give the JVM its power. The ability to easily transform code as it's loaded (or after its loaded) packs a lot of oomph.
In general I'd say that the JVM offers fewer abstractions, but more powerful ones and it offers less opportunities for hand-tuned optimizations and more for automatic optimizations. In the end, HotSpot is simply much more advanced internally. The CLR is like a car with more buttons, but HotSpot is the car with the better engine. HotSpot has always opted for constant change that's hidden from the user, while the CLR has been adding more and more user-accessible features.
The work being done on Graal/Truffle is so far ahead of anything anyone else is doing, that it will put HotSpot's JIT beyond the reach of any other technology for years to come. It seems to me that the CLR might even stop competing and C# might switch to AOT compilation, with VB possibly being abandoned. Some of the latest moves by MS seem to hint in that direction (RyuJIT was already done or nearly so).
A reference to back your statement up would be great... (i couldn't find a good one quickly). Are you aware of the capabilities of the CLR's next generation RyuJIT? What you say is at odds with what I thought, but I'd love my perceptions to be corrected if they are indeed incorrect.
Yes, some, but those differences are being quickly erased. The most important one is value types, which are being added to Java. See my reply to someone123.
RyuJIT's capabilities are nowhere near HotSpot's (I'd say they're about 7 years behind), and HotSpot's next-gen JIT (Graal) is another huge leap forward. The CLR's GC is also far behind HotSpot's selection, let alone offerings by other JVMs (there are many JVMs to choose from).
I don't think that's really historically accurate. Java and C# were pretty similar back in 2002. The .NET team was more willing to add complexity and occasionally make breaking changes, like generics in CLR 2.0.
So .Net had the advantage of coming years after Java had shown what it could be done (or not, see browser applets) from a technological and commercial point of view, AND quite a few years of development without worrying about backward compatibility.
I'm not saying Sun developers were not slow (they were), but they clearly had a much more "entrenched" position, with all that it entails.