Live data from Hacker News

Official proposal for Type Unions in C#

github.com

241–250 of 315 posts

Re: Official proposal for Type Unions in C#

#241

I’ve lost track of all of the red/blue/white/black pill color metaphors, but unions with exhaustive pattern matching is one of the toughest of all programming language features to live without once you become aware of it. I’ve never felt like I’ve fully understood the implications of the expression problem https://en.wikipedia.org/wiki/Expression_problem but my best/latest personal hypothesis is that providing extens…

I wrote this to help me understand the differences.

https://deliberate-software.com/christmas-f-number-polymorph...

Re: Official proposal for Type Unions in C#

#242

Earlier quoted context omitted.

> I don't think "type union" is a term of the art "sum type" is the term of art in Computer Science theory, but "union type" is also used. See https://en.wikipedia.org/wiki/Type_theory#Sum_type https://en.wikipedia.org/wiki/Tagged_union

At this point, calling it by its correct name (Sum Types) would leave them looking stupid for not using the correct name (Product Types) for their “records”

> not using the correct name (Product Types) for their “records”

There is no single "correct name" as there is no single "problem domain" that covers the algebra of type theory, and the pragmatics of programming in engineering, along with other areas.

Re: Official proposal for Type Unions in C#

#243
post #3

Huh, I did F# for years with discriminated unions, and I guess I just assumed C# would have had them by now. I know not everyone likes them, but for typed languages I find it extremely hard to go back to languages without ADTs of some kind. I do Java for my current job, and Java is generally fine enough, but it's a little annoying when I have to do whacky workarounds with wrapper classes to get something that would b…

> Java is generally fine enough, but it's a little annoying when I have to do whacky workarounds with wrapper classes to get something that would be done in three lines

This is a weird take, given that Java has had ADTs for years

Records https://en.wikipedia.org/wiki/Java_version_history#Java_16

Sealed classes https://en.wikipedia.org/wiki/Java_version_history#Java_17

And pattern matching for almost a year https://en.wikipedia.org/wiki/Java_version_history#Java_21

Otherwise big agree on how delightful to work with F# is.

Re: Official proposal for Type Unions in C#

#244
post #161
post #4

Earlier quoted context omitted.

F# is so hard to walk back from. I wish Microsoft would support it better and actually push it, because it's such a perfect sweet spot. Most of the functional advantages without being shackled to pure functions and the like is so easy to develop in. Instead they've been, very slowly, turning C# into F#, which is even weirder to watch.

Looking at the syntax in the type union proposal, I hope they take a bit more from F#. It really needs some work.

What are some issues you see with the current proposal?

Re: Official proposal for Type Unions in C#

#245
post #221

Earlier quoted context omitted.

But then what name would they use for tuples, which are distinct from records?

both tuples and record (structs) are product types. tuples are "untagged", records/structs are "tagged" (the members have names). sum types also have tagged and untagged variants. the untagged variants are less useful (more cumbersome) in case of sum types and hence often are not implemented in languages.

> tuples are "untagged", records/structs are "tagged" (the members have names).

Not always true in C#. Tuples can have member names

https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...

Re: Official proposal for Type Unions in C#

#246
post #221

Earlier quoted context omitted.

But then what name would they use for tuples, which are distinct from records?

both tuples and record (structs) are product types. tuples are "untagged", records/structs are "tagged" (the members have names). sum types also have tagged and untagged variants. the untagged variants are less useful (more cumbersome) in case of sum types and hence often are not implemented in languages.

C# tuple field names are an interesting case, spiritually similar to this proposal's ad hoc unions: persisted in compiled output via attributes, respected by the compiler even across assembly boundaries, but not actually part of the resulting CLR type. So, e.g., if

  var p = (x: 1, y: 2);
  var q = (u: 1, y: 2);
  var f = ((int x, int y) a) => a.x + a.y;
then

  p == q 
  f(p) == 3
  f(q) == 3
  p.GetType() == q.GetType()
are all true, but

  var r = q.x;
yields the compile-time error

CS1061: '(int u, int v)' does not contain a definition for 'x' and no accessible extension method 'x' accepting a first argument of type '(int u, int v)' could be found (are you missing a using directive or an assembly reference?)

and if

  dynamic d = q;
then

  var s = d.u;
compiles, but throws

RuntimeBinderException: 'System.ValueTuple' does not contain a definition for 'u'

at runtime, revealing the underlying CLR type.

Re: Official proposal for Type Unions in C#

#247

Really excited for this proposal as it's been the main thing I have to apoligize for when extolling the values of C#. Outside of this it's hard to think of other major features C# lacks for a language. Additionally, excited to now watch this go in and people on HN still act like C# is the same it was 10 years ago.

> it's hard to think of other major features C# lacks for a language

Heh yeah well, for better or worse, it seems to be C#’s design goal to have every single feature possible, with multiple variations of each of them. It means it’s able to cater to everyone and doesn’t turn people off the way strongly opinionated languages can. But it can make it a bit tricky to pick up.

Re: Official proposal for Type Unions in C#

#248
post #119

Earlier quoted context omitted.

Does C# impose a lot of organization? I've only worked in one C# codebase but it has partial classes everywhere and TONs of abstraction bloat. I found it difficult to reason about the organization.

C# doesn't really, but VS + the asp.net framework do. You kinda have to fight against the IDE to not do a lot of things a certain way. For example, it'll automatically namespace new files according to your folder structure. They've also turned a certain amount of automatic linting on to gently suggest/nag you to write in a particular way.Suggest you write classes in certain ways, use newer language features, declare…

> You kinda have to fight against the IDE to not do a lot of things a certain way. For example, it'll automatically namespace new files according to your folder structure. They've also turned a certain amount of automatic linting on to gently suggest/nag you to write in a particular way.Suggest you write classes in certain ways, use newer language features, declare variables in better ways, etc. You can ignore all the nagging, but it's also incredibly easy for the next programmer to walk in and use the quick actions functionality to 'fix' the code in a few clicks.

This is why I find a .editorconfig file to be incredibly helpful.

Re: Official proposal for Type Unions in C#

#249
post #12

Earlier quoted context omitted.

Instead of C#, why not F#? You get proper ADTs among many other great features, but you still get all the utility of the .NET ecosystem.

Because nobody uses it, Microsoft doesn’t invest or promote F# heavily. I’m pissed about all of this, but I accept that eventually C# will get much of F#’s goodness.

I don't think that c# will ever get immutability by default though.

Re: Official proposal for Type Unions in C#

#250
post #2

> The interior layout of the union struct is chosen to allow for efficient storage of the data found within the different possible member types with tradeoffs between speed and size chosen by the compiler. Having _attempted_ (and being bitten by) far too much black magic with C# unions in the past (using FieldOffset), there is an unfortunate situation here: aliasing a pointer/ref value and value is UB. This means tha…

Not UB, illegal. Per ECMA 335, II.10.7:

It is possible to overlap fields in this way, though offsets occupied by an object reference shall not overlap with offsets occupied by a built-in value type or a part of another object reference.

Per .NET 8.0:

  using System.Runtime.InteropServices;
  var s = new S { Bar = "Baz" };
  [StructLayout(LayoutKind.Explicit)]
  public struct S {
      [FieldOffset(0)] public UInt64 Foo;
      [FieldOffset(0)] public Object Bar;
  }
compiles, but throws

System.TypeLoadException: Could not load type 'S' from assembly 'foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.

Interestingly, this code elicits a warning

ILC: Method '[foo]Program.$(string[])' will always throw because: Failed to load type 'S' from assembly 'foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because of field offset '0'

from the AOT compiler, but none from the C# compiler.

Post reply on HN