Live data from Hacker News

.NET (OK, C#) finally gets union types

andrewlock.net

71–80 of 300 posts

Re: .NET (OK, C#) finally gets union types

#71
post #61
post #49

Earlier quoted context omitted.

Could you be clearer about what you mean, since string is a sealed type in C#, so what exactly do you mean T1 and T2 of string?

A record wrapping a string, indicating what the string represents, so you can't mix it up with a different thing also represented by a string.

Yes, you can have two different record types which both wrap a string value.

As a (bad) trivial example, you could wrap reading a file in this kind of monstrosity:

    var fileResult = Helpers.ReadFile(@"c:\temp\test.txt");

    Console.WriteLine("Extracted:");
    Console.WriteLine(Helpers.ExtractString(fileResult));

    public record FileRead(string value);
    public record FileError(string value);
    public union FileResult(FileError, FileRead);

    public static class Helpers
    {
        public static FileResult ReadFile(string fileName)
        {
            try
            {
                var fileResult = System.IO.File.ReadAllText(fileName);
                return new FileRead(fileResult);
            }
            catch (Exception ex)
            {
                return new FileError(ex.Message);
            }
        }

        public static string ExtractString(FileResult result)
        {
            return result switch
            {
                FileError err => $"An Error occured: {err.value}",
                FileRead content => content.value,
                _ => throw new NotImplementedException()
            };
        }
    }

Now, such an example would be an odd way to do things ( particuarly because we're not actually avoiding the try/catch inside ), but you get the point. Both FileRead(string value) and FileError(string value) wrap strings in the same way, but are different record types, and the union FileResult ties them back together in a way where you can tell which you have.

It's more useful implemented a level deeper, so that the exception is never raised and caught, because exceptions aren't particularly cheap in .NET.

Re: .NET (OK, C#) finally gets union types

#72
post #70

Earlier quoted context omitted.

Winforms, wpf, blazor, maui, avalonia, what are you talking about

What I don't get is why Java doesn't get dogged for desktop UI like C# does.

Because Microsoft pushes C#/dotnet as the preferred way to write UI on Windows.

Re: .NET (OK, C#) finally gets union types

#74
post #69

Earlier quoted context omitted.

Winforms, wpf, blazor, maui, avalonia, what are you talking about

Alright. I'm actually fine with WinForms and WPF since my factory floor codes depend on them. But the reality is they aren't expressive enough for modern UIs. XAML is an issue, and WPF is boilerplate hell. But then Blazor is too heavy, MAUI is broken and buggy, Avalonia is underwhelming, and WinUI 3 is an absolute nightmare.

> Avalonia is underwhelming

How? Can you elaborate?

Re: .NET (OK, C#) finally gets union types

#75

Earlier quoted context omitted.

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.

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.

The value is realized when you have both discriminated union types _and_ language pattern matching (not regex). Then it's not just a way to structure data but a way to think about how to process it.

Re: .NET (OK, C#) finally gets union types

#76

Earlier quoted context omitted.

Simple example that I use often when writing API clients: In current C# I usually do something like public class ApiResponse { public T? Response { get; set; } public bool IsSuccessful { get; set; } public ErrorResponse Error { get; set; } } This means I have to check that IsSuccessful is true (and/or that Response is not null). But more importantly, it means my imbecile coworkers who never read my documentation need…

I think I get it but I'm not really sure what I'm gaining over exception types. With an intelligent use of exceptions I can easily specify the happy path and all the error paths separately which seems really nice to me, because usually the behaviour between those two outcomes is rather different.

Exceptions are significantly slower than normal control flow in C# (about 10,000 times slower). It's also pretty non-idiomatic in both C# and most other languages I've worked in to use exceptions instead of a switch statement or similar to handle an HTTP error code. Also there can be multiple possible non-error responses from an endpoint you need to differentiate between, and exceptions would make zero sense in that case.

Re: .NET (OK, C#) finally gets union types

#78
post #74
post #69

Earlier quoted context omitted.

Alright. I'm actually fine with WinForms and WPF since my factory floor codes depend on them. But the reality is they aren't expressive enough for modern UIs. XAML is an issue, and WPF is boilerplate hell. But then Blazor is too heavy, MAUI is broken and buggy, Avalonia is underwhelming, and WinUI 3 is an absolute nightmare.

> Avalonia is underwhelming How? Can you elaborate?

[dead]

Re: .NET (OK, C#) finally gets union types

#79
I've waited for union types on C# so long that I don't even care about syntax anymore. Just give us something that works. So, I appreciate the effort, I know it's taken at least a decade to get it into this shape, and much thought has gone into it. Kudos to the team.

Re: .NET (OK, C#) finally gets union types

#80
post #66

C# is my strongest and favorite language. That said, it's frustrating that the C# framework ecosystem lacks solid options. MAUI is especially half-baked, and I'm really starting to doubt whether I should continue using XAML

C# used to be my favorite language, but having spent a lot of time in Rust using its algebraic data types + match statements + Option & Result types, then returning to C# to build a few moderately involved libraries, I'm horrified by the enums and null & error handling that I used to deal with all the time.

I knew that enums were really just named integer values and nothing more, but I had forgotten than you can build a perfectly legal enum from an integer out of the bounds of the enum's range. And a switch statement is non-exhaustive. (As I said, it had been a while since I used C# extensively.) What would have been a few lines of code in Rust turned into dozens to try to exhaustively protect against invalid input.

I know C# is a mature language that has been around for decades, but how janky everything feels comparatively really shocked me. I only very briefly played with F# about a decade ago, but my guess is that I could try to pick that up and call F# from C#, getting much better ergonomics with a combination of the two.

Post reply on HN