dotnet / csharplang

The official repo for the design of the C# programming language
10.95k stars 999 forks source link

Initial overview of unions #7967

Open BillWagner opened 2 months ago

BillWagner commented 2 months ago

This represents a first attempt at how I plan to explain discriminated unions to our customers.

BillWagner commented 2 months ago

For discussion at our working group meeting tomorrow.

IhnatKlimchuk commented 1 month ago

Does it make sense to extend this to strings? Imagine that you defined next:

public class Domain
{
    public (Data? result, "NotFound" | "NotAllowed" | string? errorCode)> Magic() {...code...}
}

That from compiler and runtime should be same as

public class Domain
{
    public (Data? result, string? errorCode)> Magic() {...code...}
}

But code analyzer in IDE can support this information, to provide useful highlight about possible cases for pattern matching. I guess that case with generics will help the most. Example:

public class Domain
{
    public (Data? result, Error<string>? error) GetData(int id)
    {
         var (record, error)= GetRecordById(id); // returns (Record? record, Error<"NotFound">? error)
         if (error != null)
         {
             return (null, error);
         }
         if (record.IsPrivateData)
         {
             return (null, new Error<"NotAllowed">());
         }
         return (record.data, null);
    }

    ...

    var (result, error) = GetData(1);
    if (error != null)
    {
        // suggested pattern matching
        var statusCode = return error.Code switch
        {
            "NotFound" => 404,
            "NotAllowed" => 401,
            _ = 400,
        }
        ...
    }
}

This could help a lot in complex domain services to use result patterns and reduce amount of throwing exceptions.

KennethHoff commented 1 month ago

Does it make sense to extend this to strings? Imagine that you defined next [...]

Literal types are something else entirely that I'd love to have but feels out of scope. Literal types don't make sense in a world without unions, but unions make sense without literal types.