5 ms·
I agree that the .NET runtime seems under invested in and the lateness to the portability game is damaging. It would also be nice to see more experimentation,
by tybit 8y ago
I agree that the .NET runtime seems under invested in and the lateness to the portability game is damaging.
It would also be nice to see more experimentation, e.g as you mention Graal, Truffle, Substrate VM and Project Metropolis all look amazing and there doesn’t seem much on the .NET side to compete other than CoreRT.
However I’m skeptical about the claims that complexity has been pushed into C# and has caused tech debt. What do you mean by that?
To me they seem to have made the right trade offs. Java is getting value types too because there’s a limit to what run times can do on behalf of developers. Spans in C# and .NET seem the way languages are moving in general with e.g slices in Go, views in C++ etc.
There are definitely some pitfalls for high performance areas but they are actively being worked on as well as ensuring the general case is better, e.g devirtualization of interfaces and abstract classes where possible in the JIT IIRC.
- pjmlp 8y agoThe only technical debt I see on C#, are little things like 3 different ways of declaring lambdas for example. As for the rest, my only complaint is that Java and C# designers should have paid more attention to what was being done in Delphi, Oberon, Component Pascal, Modula-3, Eiffel, and have offered value types, spans, low level primitives for high performance code, AOT/JIT compilers since version 1.0. And in this regard, C# fares much better than Java.
- ygra 8y agoI'd argue that copying covariant array conversion from Java was a mistake as well. Perhaps in both the language and the runtime.
- pjmlp 8y agoActually they copied it from all major OOP languages with common root object that were already prevalent before Java was designed. I am thinking about Eiffel, Smalltalk, Sather, Oberon family, Moduls-3, Object Pascal. So it was a natural mistake to do.
- peoplewindow 8y agoBy pushing things into the language, what I mean is that for example C# has stack allocation and the JIT is a very straight line compiler (for many years it was basically a C++ compiler, opts wise). The Java guys refused to add this complexity to the language and instead implemented escape analysis and scalar replacement. Now with Graal they're doubling down on that approach: there are no proposals to add stackalloc to Java, but Graal is capable of eliminating allocations in far more cases than previously. In other words Java can automatically mark things as stackalloc (sorta) without the user thinking about it, and it gets better over time. Whereas C# code does not get less allocation heavy over time. A more obvious example is value types. CLR guys put value types into the runtime and type system. Now Java is going in that direction too, but actually, the Truffle guys have demonstrated that they can specialise data structures to get the same layouts that value types give you on the fly with compiler techniques again (e.g. List<Integer> is compiled to List<int> behind the scenes when possible). And both C2 and Graal inline code more aggressively than the CLR does, and when functions are inlined together more EA is possible, so that's like passing data by value instead of by reference. So it's not really clear that Valhalla is going to be necessary in the end, if that line of compiler research is pursued further, and over the years I've been revising what I anticipate the performance improvements to be from it downwards. And finally Spans in C# are yet another example of this. Java has ByteBuffer which provides a similar abstraction, but it doesn't do e.g. array slices or access to the stack. But then again, you hardly need to think about the stack when writing Java because the runtime will use it most of the time the human would have done anyway, and the collections API offers sub-array access with inlined and fully optimised accesses. I would note that Go and C++ are both designed with AOT compilation in mind and neither are widely held up as examples of excellent language design. Overall, it's not clear that we've reached the limit of what runtimes can do. It seems more likely we've reached the limit of what runtimes written in C++ can do before they hit the sort of complexity scaling limits that make Java and C# so widely used to begin with. The speed with which the Graal/Truffle guys have been able to develop new optimisations that were theoretical for years with the C++ compiler is remarkable - even things where the more traditional branch of Java development is considering .NET style language complexification to get it.