News for hackers. Stuff that matters.
Re:dotNET (OK, C#) gets union types by glimshe on Saturday May 23, 2026 @05:40PM (#48251835)
I love C# and in every iteration we're getting more and more features to get C-like performance in a lot of scenarios. C# does it really well because if your problem isn't performance/memory-constrained, you can ignore these features and fallback on the language's natural ease of use.
Re:dotNET (OK, C#) gets union types by kensai on Saturday May 23, 2026 @08:04PM (#48252897)
Do you think by now C# has left Java behind in features and performance?
Re:dotNET (OK, C#) gets union types by gfody on Saturday May 23, 2026 @09:23PM (#48253400)
more than 10 years ago, yes
Re:dotNET (OK, C#) gets union types by paavohtl on Sunday May 24, 2026 @01:17AM (#48254615)
More like 25. C# 1.0 already had capabilities Java developers are still dreaming of, like structs / value types, properties and operator overloading. C# 2.0 in 2005 introduced generics, implemented far more competently than Java ever did.
Re:dotNET (OK, C#) gets union types by joe_mwangi on Sunday May 24, 2026 @03:49AM (#48255365)
Notice you point out features that were easy to add during the beginning where there was no concern of backward compatibility? Now that java is porting value classes to mainline and we might have them soon, and planned operator overloading through type class, I believe java approach is making careful design choices that are semantically sound, rather than adding features that create edge cases such as boxing invariants in unions like C#.
Re:dotNET (OK, C#) gets union types by mrsmrtss on Sunday May 24, 2026 @04:32AM (#48255607)
So you try to say that Java gets to be more semantically sound by making bad choices early on? That does not make sense. Those choices are very difficult fix today and many of them can't be fixed. Say what you want but semantically more sound Java won't be. And the boxing with C# unions can and will be addressed later, this was a deliberate choice by the team to bring unions earlier.
Re:dotNET (OK, C#) gets union types by lostmsu on Sunday May 24, 2026 @07:05AM (#48256293)
> and many of them can't be fixed... And the boxing with C# unions can and will be addressed later

No, they won't. C# already got itself into a corner with 32 bit arrays and 32 bit spans. And if unions are introduced as reference only that will never be fixed due to binary compatibility requirement.

Re:dotNET (OK, C#) gets union types by longor1996 on Monday May 25, 2026 @06:34AM (#48265344)
The new C# unions are not reference-only. The attribute/interface allows implementing custom union types by writing `TryGetValue`-methods instead of a single `object? Value {get;}`. The compiler handles this transparently.
Re:dotNET (OK, C#) gets union types by pjmlp on Sunday May 24, 2026 @01:57AM (#48254800)
The difference is BDFL or design by committee, a big difference between both ecosystems.
Re:dotNET (OK, C#) gets union types by stevefan1999 on Friday June 05, 2026 @08:45AM (#48411650)
Well, what's the difference between a (benefactory or not) dictator or an oligarch?
Re:dotNET (OK, C#) gets union types by brikym on Saturday May 23, 2026 @11:36PM (#48254115)
It always has.
Re:dotNET (OK, C#) gets union types by pjmlp on Sunday May 24, 2026 @01:58AM (#48254808)
Only if we ignore that nowadays JVM does a better job at being the CLR, while Microsoft has forgotten what the C means.
Re:dotNET (OK, C#) gets union types by goto11 on Sunday May 24, 2026 @03:45AM (#48255348)
C# was always better than Java as a language. The strength of Java is the ecosystem, and Java being open source and cross-platform from the beginning.
Re:dotNET (OK, C#) gets union types by littlecranky67 on Sunday May 24, 2026 @04:38AM (#48255628)
Java wasn’t open source at all from the beginning.
Re:dotNET (OK, C#) gets union types by pjmlp on Sunday May 24, 2026 @05:59AM (#48255986)
No, but it was free/gratis distributed on almost every developer magazine shipping with CDs.

One of the reasons why it took off.

Re:dotNET (OK, C#) gets union types by hackerqwe on Sunday May 24, 2026 @05:36AM (#48255896)
And the binaries, the default sdk when using java, i.e. oracle jdk, is still not open source, encumbered with a mine field of legalese. For a long time it also included malware as ask toolbar. Stay away.
Re:dotNET (OK, C#) gets union types by pjmlp on Sunday May 24, 2026 @06:02AM (#48255999)
To the point that after all the drama with J++ that lead to .NET and C# development, Microsoft nowadays is also an OpenJDK contributor with their own distributions, and official developer advocacy channels on YouTube, conferences and devblogs.

Turns out they really want to have plenty of Java development on Azure as well.

Re:dotNET (OK, C#) gets union types by pregnenolone on Sunday May 24, 2026 @07:17AM (#48256359)
Language design isn't just about adding every possible feature. For example, someone mentioned operator overloading. As someone who has written a lot of Scala, I think operator overloading would be a very bad feature for an enterprise language like Java which needs to be consistent above all else. I never understood the obsession some people have with the C# vs Java debate anyway. Generally, both languages are very good at what they do, each having its own set of advantages and disadvantages. Regardless, a developer can pick up the other language with basically no effort.
Re:dotNET (OK, C#) gets union types by xigoi on Sunday May 24, 2026 @10:30AM (#48257554)
> I think operator overloading would be a very bad feature for an enterprise language like Java which needs to be consistent above all else.

Operator overloading increases consistency. Instead of having

  int a = b + c;
  CustomNumberType x = y.add(z);
you have

  int a = b + c;
  CustomNumberType x = y + z;
Re:dotNET (OK, C#) gets union types by fragmede on Sunday May 24, 2026 @10:36AM (#48257597)
The problem with operator overloading is it makes things confusing when mixing types and let's programmers write confusing code.

    Person x;
    Job y;
    CustomType z = x + y;
WTF is Z?

Is the argument, anyway, I support operator overloading.

Re:dotNET (OK, C#) gets union types by xigoi on Sunday May 24, 2026 @11:27AM (#48258040)
> WTF is Z?

Hopefully a type error, because no sane programmer would implement addition like this. Obviously an insane programmer could, but that’s not the fault of operator overloading. The following code is exactly as confusing:

    Person x;
    Job y;
    CustomType z = add(x, y);
Re:dotNET (OK, C#) gets union types by tpxl on Sunday May 24, 2026 @01:03PM (#48259023)
I don't know; you can bit shift an output stream by a string (or char array) in C++ (std::cout << "Hello, world!"). That seems pretty mad to me.
Re:dotNET (OK, C#) gets union types by xigoi on Sunday May 24, 2026 @01:14PM (#48259112)
Are you trying to imply that Bjarne Stroustrup is a sane programmer?
Re:dotNET (OK, C#) gets union types by bonesss on Sunday May 24, 2026 @03:30PM (#48260284)
> WTF is Z?

Take a person, add a job, you get an Employee or EmployedPerson. Person.add(job).

I agree overloading can create footguns, but domain concepts should make a lot of sense in context when basic arithmetic operations are performed on them. Party = Meeting + Booze.

Custom operators are a big assistance for DSLs, and overloading can also aide their creation and elegance. Part of the “awesome but don’t be a jerk about it” toolbox.

Re:dotNET (OK, C#) gets union types by joe_mwangi on Sunday May 24, 2026 @04:03PM (#48260546)
Java’s planned approach is more like typeclass-style interfaces than unrestricted operator overloading. Types opt into core-defined operator contracts, rather than every library inventing arbitrary meanings for symbols.
Re:dotNET (OK, C#) gets union types by zardo on Monday May 25, 2026 @11:14AM (#48267844)
Yeah it's bad when it's abused, so don't abuse it.

But not having operator overloading when dealing with vectors is maddening.

Re:dotNET (OK, C#) gets union types by Salgat on Sunday May 24, 2026 @11:33AM (#48258088)
That used to be the case, but I would argue that C#'s ecosystem is just as competitive now. For our backend tech stack at work, all of our libraries used are open source nugets. Back 15 years ago, paid nugets were definitely more standard.
Re:dotNET (OK, C#) gets union types by lenkite on Sunday May 24, 2026 @04:58AM (#48255717)
Java Virtual Threads are a superior paradigm to C#'s async/await and function coloring.
Re:dotNET (OK, C#) gets union types by mrsmrtss on Sunday May 24, 2026 @06:59AM (#48256255)
I don't get what the big problem is with function coloring. You basically only need async when doing IO, and you had better know when a function does it, or you may have a bad surprise at some point in the future.
Re:dotNET (OK, C#) gets union types by oaiey on Sunday May 24, 2026 @07:56AM (#48256535)
That! Okay, in 2026 this could be a LSP feature with some editor fanciness but this is a real benefit. My nitpick is that we do not have a depreciation on the non async ones
Re:dotNET (OK, C#) gets union types by nchie on Sunday May 24, 2026 @11:25AM (#48258012)
Agreed, async function coloring makes for better structured code because it incentivizes keeping IO code near the edges while having a synchronous core.
Re:dotNET (OK, C#) gets union types by hackerqwe on Sunday May 24, 2026 @05:41AM (#48255921)
Clearly legacy heavy weight threads, virtual or not, are not superior. That’s why Swift, Rust and Typescript all chose async/await for concurrency.
Re:dotNET (OK, C#) gets union types by lenkite on Sunday May 24, 2026 @05:46AM (#48255943)
We are not taking about legacy heavy weight OS/platform threads. But "green" threads managed by the language runtime like Go. Java went the Go/Erlang way.

https://javapro.io/2026/03/05/java-25-and-the-new-age-of-per...

https://docs.oracle.com/en/java/javase/26/core/virtual-threa...

Re:dotNET (OK, C#) gets union types by kdps on Sunday May 24, 2026 @06:47AM (#48256188)
> Clearly legacy heavy weight threads, virtual or not, are not superior.

Associating virtual threads with "legacy heavy weight threads" is a fundamental misunderstanding

> That’s why Swift, Rust and Typescript all chose async/await for concurrency.

And Java chose to join Team Go/Erlang. At the end of the day, async/await is just syntactic sugar for futures/promises, which are essentially a way out of callback hell.

Besides, Rust and Typescript aren't good examples here: a green-thread scheduler (a runtime component) contradicts Rust's philosophy, while Typescript is inherently constrained by Javascript.

Re:dotNET (OK, C#) gets union types by pjmlp on Sunday May 24, 2026 @06:04AM (#48256006)
Except one of the milestones for .NET 11 is to offer similar mechanisms for async/await.
Re:dotNET (OK, C#) gets union types by biglyburrito on Sunday May 24, 2026 @07:49AM (#48256499)
Link?
Re:dotNET (OK, C#) gets union types by pjmlp on Sunday May 24, 2026 @08:59AM (#48256932)
It starts with the experiment,

https://github.com/dotnet/runtimelab/issues/2398

Which ended with,

> We have chosen to place the green threads experiment on hold and instead keep improving the existing (async/await) model for developing asynchronous code in .NET. This decision is primarily due to concerns about introducing a new programming model. We can likely provide more value to our users by improving the async model we already have. We will continue to monitor industry trends in this field.

Now three years later we have,

https://github.com/dotnet/core/blob/main/release-notes/11.0/...

> Runtime async is a major runtime feature in .NET 11 that introduces new runtime-level infrastructure for async methods. The goal is to improve tooling and performance for async-heavy codepaths. For more details and to track progress, see the Runtime Async epic issue.

Re:dotNET (OK, C#) gets union types by biglyburrito on Monday May 25, 2026 @11:24AM (#48267954)
Awesome, thank you!

So it's going to be an internal implementation change -- that is, it generates the MSIL code that's generate when a developer writes async/await code, and won't require changes to how a developer writes async/await code?

Re:dotNET (OK, C#) gets union types by youre-wrong3 on Sunday May 24, 2026 @05:57AM (#48255973)
Hahahha no. lol just no.
Re:dotNET (OK, C#) gets union types by OneWingedShark on Sunday May 24, 2026 @03:35PM (#48260313)
Both are, IMO, inferior to Ada's TASK construct.
Re:dotNET (OK, C#) gets union types by biglyburrito on Sunday May 24, 2026 @07:35AM (#48256448)
Speaking as somebody that spent 2yrs as a full-time Java dev before returning to the Microsoft stack: yes.

Java’s Optional sucks compared to how C# (and Kotlin) implement support for nullable types. C#’s async/await syntax is better than… however the hell Java says to implement asynchronous calls now (Thread? CompletableFuture? idk, I never figured it out). ffs, Java doesn’t even have support for string templates yet — they added it as a JDK preview feature (JDK 21?) and then removed it before final release.

Re:dotNET (OK, C#) gets union types by joe_mwangi on Sunday May 24, 2026 @03:58PM (#48260507)
Damn. You're old school. Java’s answer is virtual threads, not async/await. The idea is that most server-side IO can stay in direct style enabling blocking-looking code, cheap virtual threads underneath. So you don’t split the whole codebase into sync vs async functions just to avoid blocking OS threads. CompletableFuture and reactive APIs still exist, but Loom reduces the need to use them as the default application model. You can now launch millions of virtual threads to do IO.
Re:dotNET (OK, C#) gets union types by biglyburrito on Sunday May 31, 2026 @12:42AM (#48343081)
Not so much old school as I was new to JDK, there was no prior art anywhere in our codebase that implemented async (somehow, in 2022), and we started off with JDK 8 (I helped upgrade everything to JDK 17). I REALLY TRIED, OK!?

Even when I was building stuff in Kotlin, I couldn't figure out how to make async -- coroutines? RX? I forget already -- work, either. But that was all in the last few months before I left & moved back to the .NET stack.

Re:dotNET (OK, C#) gets union types by torginus on Sunday May 24, 2026 @07:52AM (#48256508)
I never liked the C#/Java comparison - Java was designed as a much higher level language, and allows reasoning about low level abstractions a lot less, while doing a ton more optimization in the JIT.

For example, GC escape analysis, automatic lock elision, devirtualization, tiered compilation are fairly recent features in C#, and likely not as mature/powerful.

Or C# has generic specialization, so if your generic param is a stuct, you get a separate implementation, while Java generics work via type deletion.

But in C# you have a ton more synchronization primitives, value types, methods are non-virtual by default etc.

This usually means that expertly crafted C# code can be faster than Java (and more importantly, you can trust the compiler to do the right thing), while if you wrote it exactly like Java, you'd probably end up with slower code.

Re:dotNET (OK, C#) gets union types by mrsmrtss on Sunday May 24, 2026 @08:21AM (#48256692)
> while if you wrote it exactly like Java, you'd probably end up with slower code.

That's not the case for some time already, at worst you get similar performance with Java and with a little effort you can get significantly better performance.

Re:dotNET (OK, C#) gets union types by hirvi74 on Saturday May 23, 2026 @07:51PM (#48252808)
I daylight as a .NET dev professionally. I completely agree with what you have wrote, but I do not think C# is particularly unique in that regard. I would say many common compiled languages are on the same path, e.g., Swift, Java, Kotlin, etc.. As time progresses, I am finding it harder to justify using C# for a greenfield project.
Re:dotNET (OK, C#) gets union types by za3faran on Saturday May 23, 2026 @08:04PM (#48252899)
> As time progresses, I am finding it harder to justify using C# for a greenfield project.

Are you able to elaborate why? Just curious.

Re:dotNET (OK, C#) gets union types by antonymoose on Saturday May 23, 2026 @08:23PM (#48253009)
Not OP here - but for me it’s the open source ecosystem. Java just wins in terms of scope, scale, and stability.

I love C# the language, but the ecosystem is a ghetto.

Re:dotNET (OK, C#) gets union types by Rohansi on Saturday May 23, 2026 @08:58PM (#48253226)
I see this reason a lot but what are some actual examples of what is lacking in the .NET ecosystem vs. Java?
Re:dotNET (OK, C#) gets union types by Amekedl on Saturday May 23, 2026 @09:23PM (#48253399)
Dev tools. The debugger is something for example that Microsoft ostensibly keeps to their own products, and how they totally slaughtered omnisharp.

It killed my daily csharp vscode driver couple of years ago, only now catching back up somewhat, but still unusable for bigger solutions.

That move made me gravitate towards vscodium, and avoiding csharp where possible.

Microsoft's move only recently got more understandable to me, because Cursor and others basically stole vscode to establish their "empire".

Re:dotNET (OK, C#) gets union types by jayd16 on Sunday May 24, 2026 @01:51AM (#48254773)
If you can use Jetbrains, Rider is on par with IntelliJ. From that perspective, both languages have a best in class debugger.
Re:dotNET (OK, C#) gets union types by 369548684892826 on Sunday May 24, 2026 @03:50AM (#48255371)
Rider is very good but this subthread is about the lack of open source dev tooling.
Re:dotNET (OK, C#) gets union types by davewritescode on Saturday May 23, 2026 @09:22PM (#48253394)
Large Apache ecosystem (Spark, Flink, Pinot) is completely missing and third-party SDKS (looking at you AWS) almost ALWAYS have worse SDKs. The java Kinesis consumer and producer libraries are amazing, the ones for C# are simple wrappers around the AWS APIs which means there's a few foot guns waiting for developers to run into, even if they should know better.
Re:dotNET (OK, C#) gets union types by Rohansi on Saturday May 23, 2026 @11:46PM (#48254173)
Good point. The majority of Apache projects are Java. Amazon is also mostly Java internally.
Re:dotNET (OK, C#) gets union types by free652 on Saturday May 23, 2026 @09:25PM (#48253412)
I mean I haven't done much in c# recently, but few examples that c# ecosystem is the subpar in quality

Kafka client library sucks, I mean it was a nightmare to make it stable and there were a few of them.

Pdfbox library

And many other libraries. If you use c# Microsoft libraries only - then you are golden. outside of that its really bad.

At this point I switched to Rust.

Re:dotNET (OK, C#) gets union types by pjmlp on Sunday May 24, 2026 @02:11AM (#48254874)
Lots of implementations and industry standards, many mix Java with OpenJDK.

It is not, Java is like C, C++, JavaScript and co.

There are many implementations, the language and runtime are evolving by industry partners, you get bare metal implementations with real time GC like PTC and Aicas (doing AOT for decades), JIT caches, cloud based JIT compilers (OpenJ9 and Azul), pauseless GC, an LLVM like compiler development framework (Graal),....

There are industry standards like Microprofile and Jakarta EE, which several vendors base their frameworks and application servers on.

And a mobile phone platform, which while isn't proper Java compliant, has enough pieces into it that makes it easier to integrate Java code and libraries, than using Xamarin.

Microsoft actually bothered with ECMA during the early days, however it hasn't been updated since C# 7.3, .NET Framework 4.8.

Re:dotNET (OK, C#) gets union types by Rohansi on Sunday May 24, 2026 @04:01PM (#48260530)
> Microsoft actually bothered with ECMA during the early days, however it hasn't been updated since C# 7.3, .NET Framework 4.8.

I know it's not a popular opinion but I don't see why they should bother. There are already multiple implementations that serve different use cases, but they are slowly converging into one. There are more languages+runtimes which do not have formal specifications than those that do, and that's okay! Fragmentation is not a good thing.

Re:dotNET (OK, C#) gets union types by JohannesH on Sunday May 24, 2026 @04:37AM (#48255623)
A good built-in/open xslt3 processor.
Re:dotNET (OK, C#) gets union types by biglyburrito on Sunday May 24, 2026 @07:56AM (#48256531)
Support for OpenAPI 3.1 in .NET sucks. Up until recently, a third-party library (Swashbuckle) has been the heavyweight, but lagged for years in supporting new features & fixing old bugs. Microsoft created a first party option (Microsoft.AspNetCore.OpenApi) that supports 3.1, but it’s nowhere near feature parity with Swashbuckle yet.

I also find serialization/deserialization to be weak in .NET. Third-party Newtonsoft was king for years, then Microsoft released System.Text.Json. Years later, it lacks feature parity, including an easy way to debug like Newtonsoft did.

Re:dotNET (OK, C#) gets union types by hirvi74 on Monday May 25, 2026 @10:50AM (#48267549)
Poor reporting libraries, PDF libraries, multiple popular open source projects have randomly gone proprietary (some after a decade+), etc..
Re:dotNET (OK, C#) gets union types by hirvi74 on Monday May 25, 2026 @10:49AM (#48267519)
GP here.

What I meant is that I try to be pragmatic when writing applications. Most languages solve most problems with relatively minor differences between them.

Of course, some languages excel in areas few or others do not. When it comes to C#, I struggle to justify when it is the “right tool for the right job.” If I were building a game in Unity, C# makes sense as it’s the only option. But if I were to build, I do not know, a FizzBuzz Widget, why use C# over any other language?

The only answer I can usually come up with is language familiarity. My employer’s answer to that question would be, “Because C# is a Microsoft product.”