I do think enforcing correctness at the type system level is a good idea for AI, which is why I often choose languages like C# and Rust over Python. However, for some things Python is definitely the correct tool for the job.
I do think enforcing correctness at the type system level is a good idea for AI, which is why I often choose languages like C# and Rust over Python. However, for some things Python is definitely the correct tool for the job.
The main reason is that you’re capable of reading it if you need to. And the recipient ecosystem expects a language. That’s why some data science communities pick R, MatLab, Julia, Python or Mojo not depending on what’s superior tech, but what their peers speak.
Very good static typing, Roslyn analyzers, good tooling and decent hot reload (for a compiled language), really good ORM (EF Core) that implements UoW and reduces a lot of the need for transaction management (simplifying the code), flexible enough and fast enough for various kinds of use cases.
Source generators are underrated as well since they can make the code very terse and legible by generating a lot of standard boilerplate.
In the interest of fairness the San Francisco version of this is also a thing: a giant, untyped ball of Rails spaghetti from the same period running on Heroku that everybody has Stockholm Syndrome'd their way into loving because of Ruby's elegance and beauty. The burden is merely shifted from a large Microsoft to a series of small SaaS companies :-)
Exceptions to this rule exist (hence my "80%") and modern .NET is lovely but it seems that the non-Java/Python mindshare is now taken up by the Golangs and Rusts of the world. It's a true shame since I do love C# for basically being a better Java.
The whole stack is open source, Kubernetes, Docker, Hashicorp tools, Postgres, Redis, MongoDB, RabbitMQ, NATS, Kafka, Prometheus, Elastic Search, Kibana, Grafana and so on and so forth.
I stopped using it because overall it feels like Microsoft has lost the plot with .NET.
Net Core, Net Framework, Net Common Core, .NET..
And God forbid any of these frameworks ever expose what they are in a config file. You start a project, hand it to a colleague and he can't figure out whether it's Framework or Core by looking at the files. You Google and are immediately bombarded by 15 year old threads.
And the .csproj files do tell you which .NET they are.
<TargetFrameworkVersion>v4.</TargetFrameworkVersion> or <TargetFramework>net4</TargetFramework> is the old framework. Also, if the file is an unreadable mess listing all .cs files, it's generally .NET Framework.
<TargetFramework>netstandard2.0</TargetFramework> is .NET Standard 2.0, which means this library can be consumed from either Framework or modern .NET.
And finally, <TargetFramework>netX.0</TargetFramework> (X >= 5) is the modern .NET.
It's really, really good now. DX is fantastic. Yes, the hot-reload will probably never match that of interpreted languages, but for a compiled language, it is good.
File-based apps are easy to get started with: https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals...
EF is solid and proven. Easy, low-lift type safety end-to-end from DB up with very good perf.
Tooling is dead simple and consistent; `dotnet build`, `dotnet test`, `dotnet run`, `dotnet ef database update`, `dotnet ef migrations add`, `dotnet tool restore`. No mix of build tools and toolchains.
It failed very often and you had to manually restart the dev process. Even when it worked, it was no where as fast as eg using Bun with TS.
Also Minimal APIs didn't have feature parity vs MVC even 4 years after release which is quite frankly insane. I hear in .NET 10 they've finally added some validation. Not sure how it compares to something like FluentValidation which still is one of the most downloaded nuget packages.
> It failed very often and you had to manually restart the dev process. Even when it worked, it was no where as fast as eg using Bun with TS
Really depends on what you're doing. For run of the mill APIs, it works pretty flawlessly with `--non-interactive` and just auto-restarts when it needs to, hot reloads when it can (again, I'm not comparing this to interpreted languages and runtimes; the constraints are just different).I have a clip of this in action with .NET 9 generating OpenAPI contracts and TS bindings at the top of this README: https://github.com/CharlieDigital/dn9-openapi-codegen/blob/m...
> Also Minimal APIs didn't have feature parity vs MVC even 4 years after release which is quite frankly insane
Why does it need to? That's like saying express should have feature parity with Nest.js; they have different use cases in my view :shrug:> That's like saying express should have feature parity with Nest.js
I disagree but, objectively, validation is a fundamental part of any web app or API.
They shipped Minimal APIs in .NET 6 without validation. The functionality was already there for MVC so it's not like they had to build it from scratch. And yet, they didn't add it until .NET 10.
Express is ostensibly the analog of minimal APIs and ships with no validation. You pick your validation library and build on top of it. A less complete, less opinionated, bare-bones stack on which you build with explicit stack choices.
Nest.js is ostensibly the analog of controller APIs and ships with validation. A more complete, more opinionated approach where you lean in to stack defaults.
This makes total sense in the Node.js world; I don't see why controller and minimal have to have feature parity when they have different use cases and, like Express, it's possible to pull down third party validation libraries. Controller API is more opinionated like Nest.js while minimal is intentionally less opinionated like Express.
From my experience it's awesome to write C# with AI. But both Opus and GLM usually one shot the modification to the file so I didn't experienced cases lately where AI had to fix compile errors. True, I gave the AI agents the lsp for C#, so maybe that helps.
Then I get the benefits of GC and strong typing.
In Rust you can use many C++ frameworks like libtorch or ONNX or specialized libraries (llama.cpp, whisper.cpp ...) via their bindings. Native projects such as Candle or Burn are not feature complete yet, but I assume they'll eventually get there and drive bigger communities compared to C++.