Hacker News new | ask | show | jobs
by CharlieDigital 1032 days ago
C# as a language seems supremely underappreciated/misunderstood.

It seems like it should have higher adoption given the performance boost over JS on Node while being syntactically similar to TypeScript (not hard to adopt for teams already familiar with JS/TS).

Combined with pretty good tooling these days and DX (hot reload is a thing), I'm always surprised by its seemingly lackluster reception.

5 comments

> while being syntactically similar to TypeScript

The guy who invented C# went on to invent TypeScript.

I've been working with C# for over 20 years. The big problem with C# in the early days was the ecosystem: an awesome language, awesome IDE, but limited libraries and bloated frameworks.

.Net Core fixed a lot of this: ASP Core works more like Express, where routing is declarative, and has no surprises. In contrast, the original ASP for .Net used reflection to infer routes at runtime, which was extremely fragile.

The way that NuGet works now is more like cargo / npm; but before that package management was either all DIY or unpredictable.

IE: Until .Net Core, you could argue that C# was a better language, but end up getting trapped in the shortcomings of the ecosystem. Now that the ecosystem is on par with Rust / Node, it's much better.

I do think there needs to be a way to smooth over the difference between sync and async APIs. Far too often the difference between an async and sync method is just copy/paste. There needs to be a way for async/sync to just JIT out to call either the sync or async method of the stream/socket/lowest level API.

Because of that lineage and syntactical similarity, I'm always surprised it's not more widely adopted by startups that need to extend beyond Node.

I've worked at one YC startup and interviewed with others. C# seems like the natural step after TS. But several were more interested in Go and Rust. Strange to me when C# seems more logical.

As much as I like C#, every time I'm on the job market, I end up taking a job in C#.

Rust's biggest advantage over C# is that it's framework-free. IE, you compile a working executable; nothing more is required.

What's harder to understand is: Will I be more productive using Rust compared to C#? (After dealing with the learning curve.) Will my code be "faster enough" to lower the cost of operations? (IE, a cluster of 5 servers instead of 15?)

Here in The Netherlands I've seen it extensively used (and I'm using it myself in some projects, though nowadays the bulk of my work is in Rust)
I was working at a YC startup which was re-writing a portion of their backend to address some scalability and performance issues. The team was already familiar with JS and TypeScript as the initial implementation was Node.

I suggested C# because of the similarity to TS syntactically while being multi-threaded and more performant for the use case but was amazed at the backlash.

It's interesting to me that many teams that are already comfortable working full stack with TS reach for Go or Rust instead of C#. I can understand Rust if a team is doing systems level programming, but C# is an easier lift than Go (IMO) for teams building APIs and apps who are already versed in TS because the paradigms are very similar (async/await, try-catch-finally, generics, inheritance, tuples, deconstruction, anonymous types, general syntax, etc.)

Yeah, I'm a huge fan of C# for web stuff. I'd take it over Rust any day, unless there are strong reasons to want a systems language.
C# really is a brilliant language, but all of the awful microsoft bullshit surrounding it ruins its image.
I’ve been using C# since 2001, before C# 2.0 and its generics rewrite and when J# was a promising star in Microsoft’s eye. There is no “Microsoft bullshit” surrounding the language any more. Microsoft runs it in production on Linux and the language (and runtime) has been transformed.

(If only we could first-class FreeBSD support…)

msbuild, entity framework, msal, visual studio and all the jank and bloat that comes with it, all microsoft bullshit which exists right now.
I don't get it.

- EF Core works great. We connected it to RDS Postgres in AWS with container instances running on T4g ARM instances.

- Our pipeline used the `dotnet` CLI to do all the builds on our local M1 MacBook Pros and in GitHub Actions on Linux runners. Want to build a .NET codebase? `dotnet build` from the CLI. Want to run it? `dotnet run`. Want to watch for file changes and hot-reload? `dotnet watch`. .NET is really, really streamlined right now. Better than Node at the moment (as a dev that works fullstack and has workloads on .NET and Node).

- Our team used a mix of VS Code and JetBrains Rider. Two devs started on VS Mac, but eventually we all ended up using VSC or Rider on Mac.

- Bloat is pretty minimal; really easy to build a console app or a web API that more or less looks like an Express web app.

Here's a 7 minute video demonstrating building a .NET web API on an M1 Mac and then pushing it into an x64 Alpine Linux container in Google Cloud Run: https://youtu.be/GlnEm7JyvyY

In my 20 some years of using .NET and C#, I don't think I've ever run into a case where I felt "this is some Microsoft bullshit".

It's continuously gotten better, but I feel that many folks still have an image of C# and .NET from back in 2003 rather than 2023.

in my 10 years of using .NET and C# i encounter microsoft bullshit most days, so i would bet money that you run into those cases all the time but just got used to it lol
if you've only used it on windows then you have constantly been running into the case of only using it for Microsoft bullshit...
I've been using it exclusively on an M1 Mac for the last 2+ years. I was just at a startup where the entire team was deploying into T4 Arm instances in AWS. Two developers started on Windows machines, but at the end, every developer was on a Mac.

I have some workloads that I'm developing on my M1 Mac that I'm containerizing and pushing into an x64 Linux runtime environment in Google Cloud.

I guess this is my point: a lot of misunderstanding and misconception about the state of C# and .NET.

What do you mean? It has great support for other platforms. I've been using it on Linux for as long as .NET Core has existed and it has always felt really natural and there are as much documentation for Linux as for Windows with the things I've been doing
Do you mean the .Net Foundation brouhaha a year or two ago around code ownership? Or Visual Studio, the product? Or simply that some people will never forgive Microsoft for embrace-extend-extinguish and as a result won't ever give any tech a chance of it originated from Microsoft?
The C# tooling is second to none. (I keep hearing rumors of native Visual Studio support for rust, but they never seem to pan out.)
Just like the Windows kernel is actually pretty good, as most of the kernel architecture and design decision predates Linux kernel by 20 years, which Linux kernel slowly incorporated in a form or another progressively.

Noticeable things such as employing hybrid monolithic-microkernel design/kernel modules/SMP/cross-platform capability existed in Windows kernel long before Linux is mainstream. An honorable mention would be the Job Object since Windows 2000, and it is the nephew of Cgroups that is a key component in the Linux Container scene. NTFS is also one of the most successful B-tree based transactional filesystem that has many hidden gems behind.

But Windows userspace things and most infamously Microsoft Office, and Microsoft's hostile and manipulative approach towards end-users makes the whole Windows thing very shitty, while I believe Linux is the other way round, the whole ecosystem is built around free and openness. In the end the tech for building the foundation of the Windows is great but the execution by the upper management is disastrous.

For C#, this is the first language that provided the now ubiquitous async/await asynchronous programming syntactic sugar to the masses. Before that, we have to use something called Begin/End pattern called APM (Asynchronous Programming Model) which is already foreseeing a CPS (Continuation-passing style) based async programming. The async/await pattern, or the state machine + futures approach quickly spread to ECMAScript, Rust and recently C++20.

Don't get me started with LINQ/PLINQ, expression tree (which is a cousin of LISP macro) and extension methods (Rust and D people should know it as mixin/traits and UFCS), which is bringing a life-changing SQL like data operation pattern, which not only runs on SQL (LINQ to SQL) but also for daily life programming. I'm very confident that LINQ predates and heavily inspired Java Stream and Rust iterator design, with Java Stream being a half-assed copy of LINQ and Rust a saner one.

Not only that, but C# lambda is also far better than Java where you can only use final variables in Java lambda, which is based on anonymous class generation (you will understand it once you turn on a Java decompiler), while C# lambda is implemented using something called "delegate", which is an analogy of "function pointer" to C/C++ and is even interoperable as a native code thunk with API marshalling. So, you can indeed store C# delegates into native function pointers and callback to C# from C++ later.

You also have first of its own FFI in C# with DllImport, and with the magic of JIT almost all C/C++/native method can be imported efficiently and directly without so much preprocessing unlike JNI/JNA in Java. No need to manage Java state and stuff in C++, just figure out the right ABI and structs, but those are up to the user to implement which is still closed under C#.

C# also have the right kind of reified generic that does take types into consideration (hence reified) unlike Java which does Type Erasure instead, and eventually making the "generic" type into nothing but a glorified Object and losing a lot of optimizations opportunity due to this loss of information.

Java only recently started to work on value type with Project Valhalla. C# already has it from the beginning.

But, Microsoft is so shitty that it binds .NET Framework to integrate with Windows heavily. They want you to stick with WPF/WCF, IIS, SQL Server and ASP.NET, which is cool in the beginning but barely evolves and is missing what others have in the long run. Plus, the hostile attitude of Microsoft towards open competitor such as Linux from the early days (remember that Microsoft once called Linux "cancer" but now tried to fully embrace it, while I'm not sure when will Microsoft extend and extinguish Linux), with a big contrast to Sun's Java (until the acquisition from Oracle, which today turned to become a hostile and threatening old Microsoft monster). As such, the development and ecosystem of .NET and C# in extension, is often being laughed at as Microsoft shut-in and the developers as Microsoft fanboys. The trend is even more pessimistic when Android adoption exploded, which uses Java as the foundation for software development. So this is why C# development staggered since 2014. There is no competition between Java and C# anymore, because Java already killed it. Barely anyone uses .NET at that point on.

.NET missed a lot of growing opportunities especially in China which is being ridiculed to this day despite many improvements over the years, although this is more of a political choice over technical choice since there are tons of Java developers everywhere in China, most of them are often hostile to C# developers because they are taught not to embrace Microsoft.

While Mono is an exception, and it once exploded with Unity Engine (but now replaced by IL2CPP), it is still a pretty niche market (well, .NET itself is already being marginalized as a niche), and I assert they must have been in the brink of getting sued by Microsoft a couple of times in the past 20 years by copying some key components of the .NET Framework. Still, the relative success of Mono in the cross-platform market is a good attempt into making Microsoft rethink their hostile strategy and is a key catalyst to gradually make .NET open.

So, Microsoft is essentially burying diamonds and gold and jewels upon piles and piles of shit. They totally have the right minds and the capability to pull off the most stunning, impressive and revolutionary tech, but there are simply too many idiotic managers that does little to no coding, with a heavier side on greedy marketing just for the quick bucks, to cockblock and kill off those innovative projects, much like the Google today.

In general, a really good write up on the strengths of C# (would you like to work on an article together? I've had one sitting in the back of my head for a while).

> But, Microsoft is so shitty that it binds .NET Framework to integrate with Windows heavily

However, this is my point: C# and .NET are sorely misunderstood. Yes, the .NET Framework is Windows-only, but .NET Core and beyond are not. For the last 2 years or so, I've been doing .NET exclusively on a Mac M1 and deploying to a mix of Arm64 and x64 Linux servers.

The bundling of .NET Framework with Windows held back C# for many years because it tied its support lifecycle to that of Windows.

The runtime changes needed to improve the language could not be made easily due to the need to support it for 10+ years.

Well, .NET Framework isn't really relevant anymore. It's obsolete.
I am not sure what the major issue is here.

Mono has been there for a very long time, and even gave life to Unity 3D.