Live data from Hacker News

Union types in C# 15

devblogs.microsoft.com

131–140 of 215 posts

Re: Union types in C# 15

#131
post #106

Hmm, they seem to have chosen to avoid names to the choices in the union, joining C++ variants and (sort of) TypeScript unions: unions are effectively just defined by a collection of types. Other languages have unions with named choices, where each name selects a type and the types are not necessarily all different. Rust, Haskell, Lean4, and even plain C unions are in this category (although plain C unions are not di…

The C and Rust union types are extremely sharp blades, enough so that I expect the average Rust beginner doesn't even know Rust has unions (and I assume you were thinking of Rust's enum not union) I've seen exactly one Rust type which is actually a union, and it's a pretty good justification for the existence of this feature, but one isn't really enough. That type is MaybeUninit which is a union of a T and the empty…

> The C and Rust union types are extremely sharp blades

Sure, but the comparable Rust feature is enum, not union.

Re: Union types in C# 15

#132
post #106

Hmm, they seem to have chosen to avoid names to the choices in the union, joining C++ variants and (sort of) TypeScript unions: unions are effectively just defined by a collection of types. Other languages have unions with named choices, where each name selects a type and the types are not necessarily all different. Rust, Haskell, Lean4, and even plain C unions are in this category (although plain C unions are not di…

Hi there! One of the C# language designers here, working on unions. We're interesting in both forms! We decided to go with this first as felt there was the most value here, and we could build the named form on top of this. In no way are we thinking the feature is done in C#15. But it's part of our ongoing evolution.

If you're interested, i can point you to specs i'm writing that address the area you care about :)

Re: Union types in C# 15

#133
post #21

Is C# a great language trapped in a terrible ecosystem? ie would masses use C# if it existed in another ecosystem? Or is it becoming a ball-of-mud/bad language compared to its contemporaries? (Honest questions. I have never used .NET much. I'm curious)

C# is a language that serves many masters and if you trace the origin of its featureset, you can see why each was created. Take the `dynamic` keyword: created to support interfacing with COM interop easier[0]. It serves many audiences so it can feel like the language is a jack of all trades and master of none (because it is) and because it is largely backwards compatible over its 20+ years of existence. That said, I…

> C# is a language that serves many masters and if you trace the origin of its featureset, you can see why each was created. Take the `dynamic` keyword: created to support interfacing with COM interop easier.

VB.NET's Object was created to support interfacing with COM interop easier. VB.NET's one key niche versus C# for many early years was COM interop through Object.

C#'s dynamic keyword was more directly added as a part of the DLR (Dynamic Language Runtime aka System.Dynamic) effort spurred by IronPython. It had the side benefit of making COM interop easier in C#, but the original purpose was better interop with IronPython, IronRuby, and any other DLR language. That's also why under the hood C#'s dynamic keyword supports a lot of DLR complexity/power. You can do a lot of really interesting things with `System.Dynamic.IDynamicMetaObjectProvider` [1]. The DLR's dependency on `System.Linq.Expressions` also points out to how much further in time the DLR was compared to VB.NET's Object which was "just" the VB7 rename of VB6 Variant originally (it did also pick up DLR support).

The DLR hasn't been invested into in a while, but it was really cool and a bit of an interesting "alternate universe" to still explore.

[0] https://learn.microsoft.com/en-us/dotnet/api/system.dynamic....

Re: Union types in C# 15

#134

Earlier quoted context omitted.

Yes, but that's just the default behavior. You can implement your own non-boxing version for performance critical applications.

Why on earth did they decide boxing by default was a sensible design decision... We have been pushing toward higher performance for years and this is a performance pitfall for unions would are often thought of as being lighter weight than inheritance hierarchies. F# just stores a field-per-case, with the optimization that cases with the same type are unified which is still type safe.

Hi there! One of the C# language designers here, working on unions. All the different options have tradeoffs. As an example, the non-boxing options tear, which can be problematic. And, we have a lot of experience implementing the simple, reference-type, approach for types that make a lot of sense to people, but then adding a lightweight, value-type version for people who care about that later. See tuples, as well as records.

I expect the same will old here. But given the former group is multiple orders of magnitude higher than the latter, we tend to design the language in that order accordingly.

Trust me, we're very intersted in the low-overhead space as well. But it will be for more advanced users that can accept the tradeoffs involved.

And, in the meantime, we're designing it in C#15 that you can always roll the perfect implementation for your use case, and still be thought of as a union from teh language.

Re: Union types in C# 15

#135
post #5

It's very disappointing that they aren't supporting Rust-style discriminated unions.

Hi there! One of the C# language designers here, working on unions. We're extremely interested in discriminated unions. A real problem is that there so much interest, with many varying proposals on how best to do them. It's a lot to go through, and we've found some of the best designs layer on standard unions. So we like this ordering to lay the foundation for discriminated unions to built on top of! :)

Re: Union types in C# 15

#136

Earlier quoted context omitted.

> terrible ecosystem .NET is a fantastic ecosystem. Has a decent build and dependency system (NuGet, dotnet run/build, declarative builds in XML). Massive standard library, with a consistent and wide focus on correctness, ergonomics, and performance across the board. You can write everything in many languages, all on the same runtime: business logic in C#; hot paths interfacing with native libraries in C++/CLI; shell…

> but sadly it is saddled with the perception that it is Windows-only, which hasn't been true for a decade In my experience it does not work very well outside of the sanctioned Linux distributions. Quirky heisenbugs and nonsensical crashes made it virtually unusable for me on Void. I doubt that's changed in the years that have since passed. > not necessarily a negative, because Windows is a decent OS Is a language ru…

> In my experience it does not work very well outside of the sanctioned Linux distributions. Quirky heisenbugs and nonsensical crashes made it virtually unusable for me on Void. I doubt that's changed in the years that have since passed.

It's open source. Did you follow the spirit of Linux to file a bug report of as much sense of the crashes as you could make? Most OSS only supports as many distros as people are willing to test and file accurate bug reports (and/or scratch the itch themselves and solve it). It seems a bit unfair to expect .NET to magically have a test matrix including every possible distro when almost nothing else does. (It's what keeps distro maintainers employed, testing other people's apps, too.)

It probably has gotten better since then, for what it is worth. .NET has gotten a lot of hardening on Linux and a lot of companies are relying on Linux servers for .NET apps now.

At the very least there are very tiny Alpine-based containers that run .NET considerably well and are very well tested, so Docker is always a strong option for .NET today no matter what Linux distro you want on the "bare metal" running Docker.

Re: Union types in C# 15

#137

Is this the last of the F# features to be migrated into C#? What a missed opportunity. I think really F# if you combine all of its features, and what it left out, was the way. Pulling them all into C# just makes C# seem like a big bag of stuff, with no direction. F#'s features, and also what it did not included, gave it a style and 'terseness', that still can't really be done in C#. I don't really get it. Was a funct…

Absolutely agree. Modern C# language design feels very much lacking in vision or direction. It's mostly a bunch of shiny-looking language features being bolted on, all in ways that make the language massively more complex. Just look at this feature: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/cs... Was this needed? Was this necessary ? It's reusing an existing keyword, fine. It's not hard to understand.…

Hi there! One of the C# language designers here, working on unions. And the author of that feature :D

So I'm happy to discuss the thinking here. It's not about saving keystrokes. It's about our decision that users shouldn't have 7 (yes 7) different ways of creating collections. They should just be able to target at least 99% of all cases where a collection is needed, with one simple and uniform syntax across all those cases.

When we created and introduced collection expressions, it was able to get close to that goal. But there were still cases left out, leaving people in the unenviable position of having to keep their code inconsistent.

This feature was tiny, and is really intended for those few percent of cases where you were stuck having to do things the much more complex way (see things like immutable builders as an example), just to do something simple, like adding an `IEqualityComparer`. This was also something that would become even more relevant as we add `k:v` support to our collections to be able to make dictionaries.

Re: Union types in C# 15

#138

I haven't read this in detail but I expect it to be the same kind of sealed type that many other languages have. It doesn't cover ad-hoc unions (on the fly from existing types) that are possible in F# (and not many non-FP languages with TypeScript being the most notable that does).

> It doesn't cover ad-hoc unions Yes and no. C# unions aren’t sealed types, that’s a separate feature. But they are strictly nominal - they must be formally declared: union Foo(Bar, Baz); Which isn’t at all the same as saying: Bar | Baz It is the same as the night and day difference between tuples and nominal records.

Hi there! One of the C# language designers here, working on unions.

We're very interesting in this space. And we're referring to it as, unsurprisingly, 'anonymous unions' (since the ones we're delivering in C#15 are 'nominal' ones).

An unfortunate aspect of lang design is that if you do something in one version, and not another, that people think you don't want the other (not saying you think that! but some do :)). That's definitely not the case. We just like to break things over many versions so we can get the time to see how people feel about things and where are limited resources can be spent best next. We have wanted to explore the entire space of unions for a long time. Nominal unions. Anonymous unions. Discriminated unions. It's all of interest to us :)

Re: Union types in C# 15

#139
post #5

It's very disappointing that they aren't supporting Rust-style discriminated unions.

These are discriminated unions, even if they may be not Rust-style.

You can see in the examples, how "switch" uses the implicit discriminant of the union to select the code branch that must be executed, depending on the current type of the value stored in an union.

The syntax of the "switch" seems acceptable, without too many superfluous elements. It could have been made slightly better, by not needing dummy variables that must be used for selecting structure members (or used in whichever else expression is put in the right hand side; the repetition of the dummy variable names could have been avoided if the name of the union variable could have been reused with a different meaning within a "switch", i.e. as a variable of the selected type).

I do not see what else do you want. Perhaps Rust has reused the traditional term "discriminated unions", which had been used for many decades before Rust, and which means the same thing as the more recent terms "tagged unions" or "sum types", with a non-standard meaning and you have that in mind.

Re: Union types in C# 15

#140
post #106

Hmm, they seem to have chosen to avoid names to the choices in the union, joining C++ variants and (sort of) TypeScript unions: unions are effectively just defined by a collection of types. Other languages have unions with named choices, where each name selects a type and the types are not necessarily all different. Rust, Haskell, Lean4, and even plain C unions are in this category (although plain C unions are not di…

Hi there! One of the C# language designers here, working on unions. We're interesting in both forms! We decided to go with this first as felt there was the most value here, and we could build the named form on top of this. In no way are we thinking the feature is done in C#15. But it's part of our ongoing evolution. If you're interested, i can point you to specs i'm writing that address the area you care about :)

Not OP but I would love to check that out
Post reply on HN