.NET (OK, C#) gets union types

(andrewlock.net)

62 points | by ingve 1 day ago

9 comments

  • glimshe 18 minutes ago
    I love C# and in every iteration we're getting more and more features to get C-like performance in a lot of scenarios. C# does it really well because if your problem isn't performance/memory-constrained, you can ignore these features and fallback on the language's natural ease of use.
  • hahn-kev 48 minutes ago
    I'm glad to finally see this making it's way into C#. Not so much because I want to use unions purely in C#. But because I want to be able to define them when interfacing with other languages.
  • rohitsriram 7 minutes ago
    F# has had this for decades, C# is basically just slowly becoming F# with a C-style syntax. Not complaining though, most teams aren't switching languages so getting these features where people actually work is better than nothing.
  • munchler 48 minutes ago
    F# leads the way and C# slowly catches up, as always. Yet for some reason, C# still gets all the mindshare.
    • correct_horse 18 minutes ago
      Haskell, OCaml, Erlang lead the way and Rust, Zig and Go get all the mindshare. I feel like its a common pattern for more experimental languages to pioneer features and other languages to copy the features and bring them to a C style syntax that the majority of devs are familiar with.
      • cultofmetatron 6 minutes ago
        Rust and Zig brought new ideas for memory management that Haskell, OCaml, Erlang sidestep having garbage control. its honestly amazing to me that they managed to get the adoption they have while being so innovative. I say this as a fulltime elixir dev.
  • moomin 45 minutes ago
    AFAICT, this means you won’t be able to define Either<string, string>, which is definitely a thing you sometimes want to do.
    • sheept 35 minutes ago
      It seems like if you wrap both in a record then it should be possible:

          public record Left<T>(T Value);
          public record Right<T>(T Value);
          public union Either<L, R>(Left<L>, Right<R>);
    • jzebedee 36 minutes ago
      C# is strongly-typed, not stringly-typed. The point of the union is to list possible outcomes as defined through their respective types.

      The idiomatic way to do this would be to parse, don't validate [1] each string into a relevant type with a record or record struct. If you just wanted to return two results of the same type, you'd wrap them in a named tuple or a record that represented the actual meaning.

      [1] https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va...

      • nesarkvechnep 21 minutes ago
        I guess C# is more strongly-typed than Haskell then... /s
    • throw1234567891 38 minutes ago
      but can you define T1 and T2 of string, then use Either<T1, T2>?
  • deadeye 9 minutes ago
    I wish the syntax looked more like typescript. This will confuse my eyes for a while.
  • Quarrelsome 47 minutes ago
    I mean yes, but also: uh-oh. I'm looking forward to reading some code that is even more confusing than the code I'm already reading.

    Not entirely convinced that I see the usecase that makes up for the potential madness.

    • Sharlin 25 minutes ago
      Discriminated union types are a really fundamental building block of a type system. It's a sad state of matters that many mainstream languages don't have them.
      • Quarrelsome 16 minutes ago
        ok, so what problems do they help me solve that I can't already solve? Is it just that we can make code more concise or am I missing a trick somewhere?
        • bigstrat2003 5 minutes ago
          I think "what problems do they solve that I can't already solve" is the wrong way to look at it. After all, ultimately most language features are just syntactic sugar - you could implement for loops with goto, but it would be a lot less pleasant. I think that unions aren't strictly necessary, but they are a very pleasant to use way of differentiating between different, but related, types of value.
          • Quarrelsome 2 minutes ago
            Ok. I'm just trying to understand what code I'm replacing with them. Like I wanna see the before and after in order to gain the same level of excitment as other people seem to have for them.

            Often the explanations just seem rather abstract which makes it harder to appreciate the win, versus the hideous sort of code that might appear when they're misused.

    • munchler 38 minutes ago
      Unions are simpler than subclasses and more powerful than enums, so the use cases are plentiful. This should reduce the proliferation of verbose class hierarchies in C#. Algebraic data types (i.e. records and unions) can usually express domain models much more succinctly than traditional OO.
      • Quarrelsome 20 minutes ago
        > so the use cases are plentiful

        such as?

        > This should reduce the proliferation of verbose class hierarchies in C#

        So just as an alternative for class hierarchies? I mean good people already balance that by having a preference for compoision.

        • munchler 9 minutes ago
          Simple example:

             type Expr =
                 | Primitive of int
                 | Addition of (Expr * Expr)
                 | Subtraction of (Expr * Expr)
                 | Negation of Expr
    • vips7L 43 minutes ago
      Union/sum types are generally a good thing. Even Java added them. They tend to be worth “the madness”. Now the rest of all the crazy C# features might be a different question.
      • dgellow 41 minutes ago
        What features do you see as crazy?
        • munchler 35 minutes ago
          All the weird cruft around nullability, for starters. Once again confirming that allowing null references is usually a mistake.
          • dgellow 0 minutes ago
            Do you mean the implicit nullable types? Now that you can make nullable explicit instead I really don’t have much issues with it. It is part of the type system, as it should, and you have null coalescing operators. Is it still problematic or are you dealing with older codebases where you cannot set the nullable pragma?
    • oompydoompy74 32 minutes ago
      You don’t see the use case for… unions? I’ve got to stop reading the comments. It’s bad for my health.
      • adjejmxbdjdn 6 minutes ago
        I love discriminated unions.

        The problem with C# is that it’s so overloaded with features.

        If you come from one codebase to another codebase by a different team it’s close to learning a completely new language, but worse, there is no documentation I can find that will teach me only about that language.

        Throw in all the versioning issues and the fact that .Net shops aren’t great about updating to the latest versions, especially because versions, although technologically separated from Visual Studio, are still culturally tied to it, and trying to break that coupling causes all kinds of weird challenges to solve.

        Then stuff like extensions means your private codebase or a 3rd party lib may have added native looking functionality that’s not part of the language but looks like it is.

        Finally, keywords and operators are terribly overloaded in C# at this point, where a keyword can have completely different meanings based on what it’s surrounded by.

        LLMs are a huge help here, since you can point to a line of code and ask them to figure it out, but it still makes the process of navigating a C# codebase extremely challenging.

        So I can see why someone may be unhappy to see yet another feature. It’s not just this one feature. It’s the 100s of other features that are hard to even identify.

        • paddim8 1 minute ago
          I am all for minimalism but "If you come from one codebase to another codebase by a different team it’s close to learning a completely new language" I really don't agree. It's not that big. Just sounds like a skill issue
      • Quarrelsome 21 minutes ago
        thanks for helping.
    • weinzierl 34 minutes ago
      A common use case for the sum type is to define a Result (or Either) type. Now, C# not having checked exceptions is not as much in need for one as Java is, but I could still imagine it being useful for stream like constructs.
      • Quarrelsome 19 minutes ago
        yeah this is the one I've considered as being mildly compelling. But don't we lose the fun of having exception handling as separate to the happy path?
  • le-mark 43 minutes ago
    I used to see some excitement around .net core several years ago. I haven’t heard or seen much in the wild. Is anyone using .net on systems other than windows nowadays?
    • dgellow 40 minutes ago
      It’s huge in the game dev world, with Unity and Godot. .net also had a reasonable community on mobile for a while thanks to Xamarin, but I cannot imagine that many people using it for new mobile projects in 2026 (outside of game dev I mean).

      It’s a very decent language (I mean C#) and runtime, I wish it had more market share in the startup world.

      • smlavine 31 minutes ago
        An enterprise shop I co-op'd at was porting one of their apps from Xamarin to MAUI when I worked there, but certainly it doesn't have much mindshare (if any) amongst SE undergrads at my university.
        • unethical_ban 9 minutes ago
          Someone I know who works with .net says that there is still no replacement for full Visual Studio for development, which is Windows only.
    • lol768 18 minutes ago
      Yes; many (Alpine/Debian) containers in K8s on GKE for production rail ticketing infra in the UK.

      There's not tons of noise being made because for the most part it all, Just Works and that's fairly boring. Perf, memory usage etc gets better every release. As an ecosystem, I'm pretty happy with it. I reach for other languages for smaller microservices.

      • gib444 5 minutes ago
        > rail ticketing infra in the UK

        You mean Raileasy? Or RDG too? (Just curious about the stack of the wider rail tech infra)

    • bel8 20 minutes ago
      I consulted for multiple enterprise C# projects in the last 5 years. At least two of them are 1mil+ lines of code each.

      All of them run in Linux servers.

      Some of them were ported from PHP and Python to C#.

      Plus LLMs thrive in strongly typed languages.

      Which means C# will keep being very strong in enterprise too. Not only in games where it reigns a large chunk if the market share.

    • forgotaccount3 36 minutes ago
      Yes, lambda's and our dev's use mac's so it enables that. We deploy some apps to some unix based server as well but the company is mostly windows servers anyway.
    • yread 35 minutes ago
      Wwwuuuuuaaahhhhh! (making a big wild excited noise using asp.net core exclusively on Linux servers since 2017)
    • b65e8bee43c2ed0 27 minutes ago
      it was an obvious marketing campaign. back then core and blazor were shilled relentlessly, and the artificial excitement died the moment MS moved on to shill vscode and typescript.

      companies spend a lot on marketing, and it's not just ads.