Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Which is a shame, because C# is usually better at the problems many startups try to make Go work at. It is a significantly stronger offering if you treat it as a middle ground between C++ and Rust family and Go/Java family.

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!



I can understand advocating for C# over the mess that is JavaScript, but with Go, it’s a different story.

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.


    > ...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


Wow. That looks painful.

Sigil soup!


It depends on what you're doing.

Very useful when your workload involves a lot of steps of ETL (small throwaway functions and throwaway intermediate data types)


> 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#.

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.


>Not once have I ever had to interact with these technologies in a way that would benefit from my application using the same language.

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.


As a counterpoint, I have many times had to interact with the those technologies, and thus been able to use their source code as packages and/or learn their source code techniques which I have then used in my own Go programs.

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."


In Kubernetes at least you may benefit from the ability to write custom conteillers. But I agree with you that the need for this is relatively niche.


I run a monitoring startup (StackScout) where I'm rewriting the main API from PHP to C#, but the actual agent you install on your servers (so typical systems programming) is and will stay written in Go. It's ok to not have all your tech stack in a single language.


At Doordash, we regularly do it and interface with these tools to build custom solutions.


I really should up my shill game...not even in a top 10 language shills on hackernews nowadays :(

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.


> faster than C# for most workloads.

Which workloads? In all benchmarks I've seen and made myself C# has always been faster.


Concurrency, startup time, memory usage, I/O bound workload.


I'm not an expert but from the benchmarks I've seen C# consumes considerably less memory than Goroutines.

Eg: https://alexyakunin.medium.com/go-vs-c-part-1-goroutines-vs-...


All these .NET has better performance at. Go explicitly trades it off for smaller memory footprint. (Yes, even the things Go is supposed to be good at, because NativeAOT is a more "high-end" solution to the problem - more scalable binary size, and borderline absent startup overhead).

Also finely grained concurrency has especially big gap: https://hez2010.github.io/async-runtimes-benchmarks-2024/tak...


People can over abstract in almost any language. The problem is that most developers, especially beginners, are not great at finding the right balance. What you miss is experience in good design.

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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: