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