C#. No Type Erasure. More powerful reflection with less code. Not to mention the unbelievable power of Roslyn and being able to programmatically generate code with little effort.
If you love Java reflection, your mind will be blown by C#'s.
The huge problem is that it's not that much better than Java which has ~50X more open source software written for it. The day MS makes a bytecode transpiler so I can use my Java libraries in C# I'll never touch Java again. The languages are so similar I have no idea why they haven't done it yet
I always see the .net fanboys tout how much better C# is than Java with generics, await/async, etc. but at the end of the day it's not that much better when you can achieve the same thing in Java with better open source support and across oses.
I know there's .net core now but I am not going near it until it matures.
LINQ -> streams, QueryDSL, RxJava, JOOQ etc
Async/await -> Comsat/Quasar
The type system is lightyears better in C# but it was rare that I needed those features. Usually you can hack around the limitations and end up with something (slightly cruftier) that does the same thing in Java. Mockito, Retrofit, and RxJava are good examples of hacking about the type system until you have something good enough. That said, there are definitely times I still miss C#'s stellar type system. Easily the best of any language I've touched besides maybe Typescript (which is designed by the same guy)
Yadda yadda, if I wanted to "fix" the lack of an open source community in C#, I'd start with the Unity3D community.
Python as a scripting language makes sense, in this arena, anyways, as it's the scripting language for Blender. A single scripting language for 3D software and game engine in a game studio just makes sense.
I can go for a coffee when Blender does some kind of data transformation, I can't do that in a middle of a rendering a frame 60 times per second.
Meanwhile, the interesting technologies, especially relating to web development, ops/deployment, or data storage and processing are first-class citizens in Linux (and macOS gets a free ride, because POSIX and desktop). Most of them don't use Java , but enough do: Lucene/ElasticSearch, Cassandra (and probably DynamoDB, even if it isn't OSS), Hadoop, Neo4j, Kafka, and more.
It's not even close. Please understand I'm not hating on C#, or saying Java was why these things are successful (definitely not), but I think it helps to understand the eco-systems surrounding both C# and Java. C# may be a nice language, and may be able to run on Linux. In 2005 (C# 2.0) it was almost revolutionary, but now it's just another language. Meanwhile everybody else has been learning and using the other languages to build great things - distinctly without Microsoft.
I agree with all you said, but i'm referring to the previous comment where ms has been all but asleep in the last 10 years :D Anyway talking about language and dev-environment are two completly different conversations, and i'm not wrong saying that Java as language stagnated far too long. I never said the .net eco system thrived meanwhile :D
the languages are so similar because microsoft started with J++ and got a lawsuit from Sun (https://en.wikipedia.org/wiki/Visual_J%2B%2B).
https://www.codeproject.com/articles/1440/introduction-to-vi...
https://www.microsoft.com/en-us/download/details.aspx?id=471...
> It's funny when Java users complain about type erasure, which is the only thing Java got right, while ignoring all the things it got wrong.
I do bare metal/low level embedded, kernel drivers, and occasionally shared libraries. Java is useless for practically all of my typical use cases.
https://www.ptc.com/en/products/developer-tools/perc
https://developer.android.com/things/
Of course it isn't suited when trying to fit something into PIC with 64KB.
You can also make shared libraries with Java these days. Look at SubstrateVM. It turns Java code into a .so file that doesn't depend on the JVM, compiled ahead of time, with a C API exported.
> Look at SubstrateVM. It turns Java code into a .so file that doesn't depend on the JVM, compiled ahead of time, with a C API exported.
Thanks, will do. I've been mostly eyeing Webassembly for some "cross-platform shared object" use cases.
Java's real issues like in two aspects: 1) Bad Java programmers have built a culture of writing "overpatterned" enterprise code (with FactoryBuilderFactorFunctions) 2) Horrible GC/iffy performance for a modern language
#1 is reason enough to avoid Java like the plague. #2 makes it totally unsuitable for heavy numerical computation or systems level applications. Nothing like huge GC spikes to liven up your day.
2) Without a doubt native shines here. I’ve also been a victim of those massive GC spikes in the past. But I think saying the JVM has horrible GC seems a bit hyperbolic as it’s quite matured and more than adequate for most usecases.
Speaking as someone moving from Ruby to Go, I actually like the strong stance that Go takes against magic. The original article acknowledges that Go works the way that it does by design, and acknowledges the reason very fairly: the language is firmly on the side of making code easy to read, even at the expense of making it less elegant to write.
Rust and Nim provide the sort of thing I mean, hygienic macros - they're nicer than reflection because you keep type safety and you keep run-time performance without generating a bunch of transient source files. Nim's also got a nice RTTI interface, too.
When I have to do Java, I keep recalling Brazil[0].
Sure, if you look at JEE stuff, you'll run into it...
On the contrary java has been around since 1994. Who knows how mature golang and python will get after aging and maturing like java.
I'm not sure why people harp on the JVM so much. JavaScript uses a runtime with even more magic that uses 5-10x as much RAM. I think the crappy JVM's of the past along with bad memories of Java Applets tarnishes its reputation unfairly
Not only do you get instant startup, you also get a statically linked binary that doesn't need a JRE present to run. Throw it a JAR - get a native binary for your system.
People are starting to experiment with AOT compilation via graal to make headroom in this space, but the techonology being used feels young, nascent, and experimental or immature:
https://medium.com/graalvm/instant-netty-startup-using-graal...
https://www.innoq.com/en/blog/native-clojure-and-graalvm/
Interestingly most high-level runtimes also have slow startup, including python, ruby, and node.js, but java's feels worse because people seem to want to use heavyweight frameworks like spring or aspectj that absolutely murder startup time, that for instance generate bytecode on startup or use classpath scanning to discover dependencies.
Newer frameworks like Vert.X and Dropwizard address this pretty well. We have a fairly large Dropwizard project that still starts in ~5 seconds. Also some written in Spring MVC that take 2 minutes...
Also, God AspectJ let's you create horrible abominations. And it feels like it was designed to encourage you to do so. A great example of why you shouldn't always use self modifying code even if it's easy to do.
Java 10 is slightly better but still slower than Java 8 by default. Enabling app CDS gets you back to comparable performance to Java 8. With AOT enabled (in addition to app CDS) it might be faster, but that just crashes on machine (and only works on Linux anyway).
So don't get your hopes up too much.
Almost all third party commercial JDKs have some form of AOT support.
"Casual" Java programmers usually miss the most important feature, what really makes it possible to do almost anything in Java. Reflection and runtime code generation. Every time I look at Go this ends up being a problem, worse than lack of generics. A lot of Java libraries use these features under the hood to make things like JPA and JSON serialization work.
Nothing I'm aware of comes close to Java in this, where you can redefine the language and rewrite compiled code at runtime while still maintaining execution and memory safety. Java agents, annotation processors, and libraries like JavaAssist, ByteBuddy, and ASM make seemingly impossible things pretty easy to write.
This is why annotations are used for everything in Java. They're often just tags used to find targets for rewriting code at runtime.
I was trying to write a thin ORM for Go and quickly found out it was impossible to do what I needed without blowing a bunch of nasty generated source files into the build. In Java, I can give the developer a nice clean interface and just generate the code when the app starts. Go forces you to expose all this to the user of your library