I guess everyone likes to be the underdog, but thruth is the B2B space is dominated by the duopoly of Java and .Net and shows no signs of changing.
The author is imho cosplaying as a contrarian while being solidly mainstream.
I guess everyone likes to be the underdog, but thruth is the B2B space is dominated by the duopoly of Java and .Net and shows no signs of changing.
The author is imho cosplaying as a contrarian while being solidly mainstream.
I think that it's also much more common with companies that aren't primarily tech-focused, as those companies usually have cosy relationships with Microsoft. Pure tech companies, startups and FAANGs don't seem to use it much.
This also ties into geography. In the US, far more people work for startups, FAANGs and pure tech companies than in Europe, where traditional businesses and "software houses" are far more prevalent, which means there's far more C# there.
It is the cool and modern language in today's landscape. But it is popular among the companies which use it the opposite way. Now, we shouldn't complain too much. Because this is what made .NET survive in the first place. But I wish more people looked at projects like Garnet, Ryujinx, various greenfield HPC and highload libraries in the ecosystem over yet another CRUD template. Business domain modeling is much better done in F# anyway!
Startups choose Go because no one I know is excited about working with GoF-style OO code these days. It’s easier to hire for and faster than C# for most workloads.
Yes, you can write C# in a data-oriented way, but no one does. So diving into an existing codebase means dealing with OO encumbrances, and not everyone wants that.
The compilation time is fast, and so is the startup time. Cross-platform compilation with a single command and a single binary makes life easier. On top of that, most infra tooling—Grafana, Prometheus, Kubernetes, Terraform—is written in Go, so choosing Go for the backend comes with a ton of advantages over C#. I can personally attest that this is exactly why Uber and now DoorDash have chosen Go over the alternatives.
Also, no. Go comes with certain limitations C# is completely free from. It's a stronger language for greenfield projects :)
And if you are intentionally writing bad code, Go is much more fragile when you do so. It is extremely unlikely a startup would write C# in the style you dislike. Such style is not even inherent to C# and you will find plenty of convoluted and overabstracted Go code now that there is an influx of developers in Go ecosystem moving from other languages. And a good deal of really verbose and equally hard to read code added by new features as Go tries to tackle the projects of complexity it was not designed for.
Now Go handles that by delivering a deliberately limited language. This has its pros when you have a load of hires fresh out of college.
Some wise people saw it from the beginning that the language designers had went too far with their limits, and so now things need to be bolted on the language. But I think some choices are unfortunate and cannot be repaired.
------------
If you want to go functional, want a powerful Hindley-Millner type system that is not too advanced, you should look at F#. You have the full SDK, you can still sprinkle in some OOP, have C# and C interop, you can still declare some types as mutable if needed, you have proper SUM types... the list goes on.
But in my view, no language can replace design skills. A good team has at least one senior who primarily coaches juniors wrt to design.
Not once have I ever had to interact with these technologies in a way that would benefit from my application using the same language. The language they are written in is irrelevant.
You haven't had to or refuse to? I've interacted with plenty of C# teams in my career and getting them to step outside the box to solve an actual technical problem in a reasonable way is _painful_ for this very reason.
They'd rather set up a meeting or hire more consultants and stonewall a project for over a year.
Most programmers can learn and pick up C# in like a day, but Windows-based developers seem to have a lot of trouble going the other way.
What does that prove? it proves that no single developer's anecdotal evidence can be used to validate a broad-brushed claim like "The language they are written in is irrelevant."
> ...no one I know is excited about working with GoF-style OO code these days
FYI, this is C#: var namedFunctions = new Dictionary<string, Func<int, int, int>>() {
["multiply"] = (int x, int y) => x * y,
["add"] = (int x, int y) => x + y,
["subtract"] = (int x, int y) => x - y,
["divide"] = (int x, int y) => x / y,
};
log(namedFunctions["add"](x, y));
This is also C#: var multiplyN = (int[] numbers) => numbers.Aggregate(1, (a, b) => a * b);
var addN = (int[] numbers) => numbers.Aggregate(0, (a, b) => a + b);
var subtractN = (int[] numbers) => numbers.Aggregate(0, (a, b) => a - b);
var divideN = (int[] numbers) => numbers.Aggregate(1, (a, b) => a / b);
log(multiplyN(new[]{1, 2, 3, 4}));
log(addN(new[]{1, 2, 3, 4}));
log(subtractN(new[]{1, 2, 3, 4}));
log(divideN(new[]{1, 2, 3, 4}));
As is this: // Return a tuple
var runCalcsAsTuple = (int[] values) => {
return (
multiplyN(values),
addN(values),
subtractN(values),
divideN(values)
);
};
// Destructure the tuple
var (
multiplyResult,
addResult,
subtractResult,
dividResult
) = runCalcsAsTuple(new [] {2, 3, 4, 5});
Named tuple types are also kinda interesting: using Profile = (
string Username,
(string Hn, string Mastodon) Socials
);
var profile = GetProfile();
var (hnHandle, mastodonHandle) = profile.Socials;
Profile GetProfile() => ("chrlschn", ("CharlieDigital", "@chrlschn"));
If you haven't looked at C# in a while, I'd recommend taking a look with a fresh set of eyes.Small repo with examples comparing C# to JS and TS: https://github.com/CharlieDigital/js-ts-csharp
Sigil soup!
Very useful when your workload involves a lot of steps of ETL (small throwaway functions and throwaway intermediate data types)
Which workloads? In all benchmarks I've seen and made myself C# has always been faster.
Also finely grained concurrency has especially big gap: https://hez2010.github.io/async-runtimes-benchmarks-2024/tak...
Eg: https://alexyakunin.medium.com/go-vs-c-part-1-goroutines-vs-...
I’m loving the fact that the industry is getting tired of Node in the backend and the tech debt it incurs after a few years. Rediscovering old values and getting excited about them is perfectly okay. Nobody remembers all of history—reinvention is part of the process.
Thus, anything that gets in the way of that is not worth it.