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

They're doing the same thing with C#. The amount crap they have added to that language over the years is mind boggling - yet, we still don't have sum types which is the one thing that every C# developer I have worked with _really_ wants.


I have mixed views on this. We’ve gotten a lot of good with the bad. I think “C#, the Good Parts” would be a much thicker book than “JavaScript, the Good Parts”


I agree. Most things that got added are good.

I don’t like that there are 3+ ways of checking if a value is null tho.


There’s like 3+ ways to construct an object too.


Have you seen cpp?


That in itself is a critique of C#


Maybe, it's not my favourite language, but it seems basically fine. A new version drops, my five, ten year old code largely still just works and maybe there are improvements I have a use for in new code.

Some of the remaining warts are because it is wedded to the .NET CLR, so if the CLR says you can't do that then, too bad C# can't do that. It would not be practical to do anything about those.


Could you list the features you consider crap?



Yeah, I'd like to see this too...

We're discussing Windows and all its ad-ware/invasive changes, and someone brings up C# without giving a real explanation or examples.

The last few C# versions brought primary constructors, collection expressions, records(!), tons of Span<T> improvements/support, etc. I just flicked through the list, and nothing that stuck out to me as being bloated.

The main bloat C# has is older stuff that you really shouldn't be using anymore (e.g. ArrayList, dynamic, Thread, delegate keyword, etc).


"Bloat" is just shorthand for "things I don't like"/"things I don't find useful". It has no other meaning. Avoid using it where possible.


> We're discussing Windows and all its ad-ware/invasive changes, and someone brings up C#

I brought up C# because the article discusses a Microsoft Windows design philosophy that I feel is also reflected in their approach to C#. It’s a Microsoft thing.

I agree with you that the examples you mention were great additions to the language! But I still think the C# design team has some seriously screwed up priorities. My theory is that this one year cycle they are on is hampering their ability to make changes (like sum types) that require more than a year of work.


Could you give some examples of the bloat they've added to C# that represent their "seriously screwed up priorities" aside from not adding Sum?


See the links I listed above. None of those features solved a language problem as large as the lack of sum types. It baffles me that they even spent time on them before providing a feature that is in such high demand (and has been for more than a decade).

I understand that you shouldn’t always give users what they ask for - but this is something that has picked up steam in other languages because it’s actually useful and makes code bases easier to maintain.


You're projecting your strong opinion on others.

I've used C# since 2008 for business software and high performance computing. I've not missed sum types at all. Most of what was added is something I see a lot of value in. I don't like that it, by design, obsoletes some older parts of the language, but that's about it.

I'm now using C# on linux almost exclusively. No complaints from me!


It's anything but a small language, but I wouldn't consider the stuff they're adding crap. They're useful features, but yes, this does have a price and makes the language larger.

There is value in a language with minimal syntax like Go, but it's not the only choice. C# is a pretty nice language overall, even with all the warts. But every language people actually use does have ugly stuff somewhere.


If you're creative about it you can make an interface for what is essentially a sum type.

All it takes is a method signature like:

   Z read<Z>(Func<A,Z> readA, Func<B,Z> readB)
It's a bit of a Yoneda embedding like way of forcing it in to the language, but hey it works.


I think I'm missing something.

Presumably, you use a function like this to represent your sum type containing the value "avalue":

    (readA, readB) => readA(avalue)
The problem I have is that when you create this function you have to reify the return type Z. You can't use this value in arbitrary contexts where the accessors need to return different types.

How do you get this to work?


You want to return different types depending on the branch?

I mean you could return a sum type if you really need to.

Formally a sum type is just something that turns a pair of functions to Z into a single function from the sum type to Z. In fact it shouldn't do more than that.


No, in any particular use of the value both branches return the same type Z.

But when I want to use the value in two different places I don't want Z to be the same in both places.

That's where I'm stuck. When I instantiate the function that represents a value of the sum type I need to choose a return type Z, which is locked in for every use of the value.

I think I understand the idea. I don't see how to make it work in C#.


Yep, this is exactly the approach we take. It works ok-ish, but it’s far from elegant. In our case ‘read’ is ‘Switch’. I think it’s a fairly common pattern in C# these days.


You can emulate sum types with classes and inheritance (N classes inherit from an empty base class), can't you?


It's very clunky


Yes, very clunky. One of the big issues with this approach is that switch expressions still require a default branch because there’s no way in C# to express a completely closed set. This makes future changes to the set (sum type) hazardous.

They continue to fiddle with design approaches to solve this. See https://github.com/dotnet/csharplang/blob/main/meetings/2025...




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

Search: