Live data from Hacker News

Official proposal for Type Unions in C#

github.com

61–70 of 315 posts

Re: Official proposal for Type Unions in C#

#61
post #32

I find it strange and slightly confusing that tey call it "union types". The correct term would be "sum types" or "discriminated union types", union types being the union of two types with no distinctive tag between the two cases. E.g. |Int ∪ Int| ≡ |Int|, while |Int + Int| ≡ 2 |Int|

> I find it strange and slightly confusing that tey call it "union types". The correct term would be "sum types" or "discriminated union types"... You mean like this? > A proposal for type unions (aka discriminated unions) in C#. Discriminated unions are a type of union type, hence the name, and in terms of how they're used in everyday development they fill a very similar role. If they have no intention of supporting…

I've read the proposal, and I'm just pointing out that "aka discriminated unions" is incorrect or at the very least confusing. Call it "sum types" if you don't like the term "discriminated union types", it's both correcter and shorter than "union types"

Re: Official proposal for Type Unions in C#

#62
post #50

Earlier quoted context omitted.

Do note that record types aren't closed even with a private constructor. The compiler will generate a protected constructor for copy operations which can then be inherited from. To prevent this, you have to define your own protected constructor and have it throw a runtime exception if it isn't a valid case.

You are technically correct (the best kind of correct), but in practice I've not found this to be a problem, certainly not something that is ofsetting the vast usefulness of this data pattern.

I've found the same to be true as well.

Re: Official proposal for Type Unions in C#

#63
post #35

Earlier quoted context omitted.

C# is great, likely the best mainstream programming language nowadays, but its in the hands of microsoft and microsoft didn't really care much about building a community or getting it to work natively in other OSes/toolchains. Its a shame, they even had a second change when Oracle bought sun and no one knew what was going to happen with Java, but fumbled that as well.

https://isdotnetopen.com/

This always shows up. Comical.

Re: Official proposal for Type Unions in C#

#64
post #18

What would the rough timeframe be for seeing adoption of this into the language? I was considering introducing the OneOf library into our codebase, but if this is < a year or so away it might not be worth the effort.

It's not a bad idea to evaluate OneOf. This proposal relies on records, so every use instance requires heap allocations and dereferencing which has memory and time implications respectively.

I implemented my own option types entirely differently via ref structs where the "non-option" becomes either a default of a value type or a null reference (size of a pointer). Then (in theory) the overhead is reduced to a single dereference with everything else being stack-allocated.

I then built the same thing as a non ref (regular) struct version for storing in a field. So I have Options.Quick and Options.Long namespaces with practically the same struct design just the former is a ref struct.

This has served me very well, is very fast. It just doesn't have the exhaustive checking and risks derefing a null reference, but in practice is not a big issue.

   if(option.IsT1){ doSomething(option.ValueT1)};
   if(option.IsT1){doSomething(option.ValueT2)}; // this would throw an exception, i.e. a bug, but its very readable to catch the bug

Re: Official proposal for Type Unions in C#

#65
post #14

Earlier quoted context omitted.

I do like Scala, and I haven't touched Scala3, but I've found it pretty unwieldy for actual use. It feels like I'm constantly fighting with the type system in a way that ends up being annoying an unpleasant. To be clear, it's not like I'm new to functional languages and their type systems, I've been doing Haskell for forever, and I did F# for a multiple years, but Scala has never really clicked for me. Personally, fo…

> I definitely recommend giving F# a try. I think it's an extremely underrated language. Do you have any recommendations for people who do not have C#/.NET experience who want to rip their toes in F#? The last time I tried the language I bumped my head on the .NET parts. :/

Out of curiosity, what confused you about the .NET stuff? I didn't have any .NET experience going into F# either [1] and I didn't find it too hard to pick up the .NET stuff.

For the most part I didn't need most of the built in .NET libraries; the F# stuff was fine, but the ones I ended up using a lot were the threadsafe libraries for when I needed mutation across threads. ConcurrentDictionary was one I used an awful lot, ConcurrentBag occasionally, SemaphorSlim, and Interlocked Incrementors.

The reason that the .NET compatibility was handy to me was because it made it easy to get third party libraries without much fuss, which was great because they were generally pretty well supported.

The rule of thumb that I used was that F#, while it kind of looks like Haskell, is not Haskell, and specifically it's not lazy, and as such I always kind of pretended I was in the `do` block. Things execute top down, and you can mix in side effects wherever, so you kind of have to pretend everything is in an IO monad, or at least if you see anything that has a side effect in there.

[1] I was hired at Jet.com specifically because I had Haskell and Erlang experience prior. I had never written any significant C# code before.

Re: Official proposal for Type Unions in C#

#66
post #38

Earlier quoted context omitted.

I get the feeling F# is a second-class citizen in the ecosystem. How likely is it (or is it at all possible) that I'm going to run into some library that doesn't work with F#?

It's impossible for a .NET library to not work with F#. It's very possible (and even likely) for a .NET library to prevent you from writing idiomatic F#. You're right that it's a second-class citizen.

> It's impossible for a .NET library to not work with F#.

This isn't true, C# has been adding new ABI features that didn't interact correctly with F# until the compiler and tooling catched up. For example, the spanification of C# was a huge a pain point and it still is when it comes to tooling.

Re: Official proposal for Type Unions in C#

#67
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.

F# has it's own warts, tooling isn't as polished, stuff like type providers sound really cool but suck in practice IMO, file ordering being relevant for compilation is bleh... Every time I try to use it I'm left with a feeling it's not worth the hassle over C#. C# has been quite nice for 10 years and they keep improving consistently with every version.

The language itself is nice, the code bases that companies produce with it is not, and sadly that reputation plays into your decision to choose a career stack.

You're going to have patterns from the .NET Framework era being ported to .NET Core projects. It works, but you'll have two paradigms of doing things mixed into your project.

I envy people who only do hobbyist C# so get to work on code bases that have all the newest language feature usage.

Re: Official proposal for Type Unions in C#

#68

Every time the question of preferred programming languages comes up, I'm usually in the extreme minority with my preferences being Rust (for small/fast) and C# (for productive and easy, where GC is acceptable), a combination that doesn't seem to appeal to too many people. But for the projects that fall right about in the middle where it could go either way and I could see either language working, I almost always pick…

It's possible to add DUs in C# today with some third party packages.

- https://github.com/domn1995/dunet

- https://github.com/mcintyre321/OneOf

Quite good and ergonomic with the source generators removing a lot of the boilerplate.

I have a practical example here using OneOf with .NET Channels: https://chrlschn.dev/blog/2024/07/csharp-discriminated-union...

Re: Official proposal for Type Unions in C#

#69
post #53

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…

Maybe I'm off, but to me the gist of the expression problem can be explained by contrasting how code extensibility is achieved in OOP/FP. OOP Approach with interface/inheritance: Easy: Adding new types (variants) of a base class/interface. Hard: Adding new functionality to the base class/interface, as it requires implementing it in all existing types. FP Approach with Discriminated Unions: Easy: Adding new functions.…

I think you've nailed the definitions.

However the definitions make the 2 choices (adding new types vs adding new functions/operations) sound like a toss-up.

It is the fact that I tend to find the FP/DU approach so much more frequently useful for my/my team's own code that makes me wonder if I'm missing something.

Perhaps the important distinction I've been missing is in Wikipedia's definition:

"The goal is to define a data abstraction that is extensible both in its representations and its behaviors, where one can add new representations and new behaviors to the data abstraction, without recompiling existing code, and while retaining static type safety (e.g., no casts)."

... but when I'm working on my own/team's code, it is perfectly sensible to recompile the code constantly.

Re: Official proposal for Type Unions in C#

#70

Earlier quoted context omitted.

> It's incredibly hard to go back to a language without even basic ADTs after seeing the light. How did we ever prioritize implementation inheritance over ADTs? I don't know, but it was a mistake.

How widely understood and appreciated were algebraic data types at the time Cfront was first floated as the precursor to C++? To what degree had they shown up in mainstream languages?

Well if you want to compare to why C++ has multiple inheritance, you need to first explain which mainstream languages in the mid-1980s had multiple inheritance so we can contrast.

Like algebraic data types, multiple inheritance wasn't novel, but what were the big famous languages from that time which showed this was a must have for Bjarne's language?

Post reply on HN