6 ms·
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 t
by Quarrelsome 5mo 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.
- vips7L 5mo agoUnion/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 5mo agoWhat features do you see as crazy?
- munchler 5mo agoAll the weird cruft around nullability, for starters. Once again confirming that allowing null references is usually a mistake.
- dgellow 5mo agoDo 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?
- munchler 5mo agoYes, all that stuff. I try to stick to F# where no special syntax is required for missing values (via Option<T>).
- setr 5mo agoGiven that they already made the billion dollar mistake, I find their handling for nulls the best possible thing they could do at this point. I’d hardly call it crazy — rather, it’s exceedingly pragmatic.
- vips7L 5mo agoPersonally I prefer T? over Option[T]. Monads just add extra typing and destructuring for no reason. It’s definitely the pragmatic choice.
- vips7L 5mo agoMaybe not crazy but the language just has a really broad surface. I find it to be like the Scala of the OO world.
- munchler 5mo agoUnions 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 5mo 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 composition.
- munchler 5mo agoSimple example: type Expr = | Primitive of int | Addition of (Expr * Expr) | Subtraction of (Expr * Expr) | Negation of Expr
- Quarrelsome 5mo agoIsn't that just Func<int> ?
- afdbcreid 5mo agoReally not. You can, of course, having instead a delegate to evaluate the expression. But then that's all you can do. You can't pretty-print it, for example, or optimize it, or whatever.
- deleted 5mo ago[deleted]
- LeFantome 5mo ago“Compoision”. A typo I know but it would be a word describing what goes wrong with class hierarchies.
- weinzierl 5mo agoA 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 5mo agoyeah 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?
- exkgkkwksk 5mo agooo and support for exceptions, in particular checked exceptions, was a mistake of the 90s. We know better today, there’s a reason for why modern languages like go/rust/swift don’t use them, and why many use c++ with exceptions disabled.
- vips7L 5mo agoChecked exceptions are great. There is no difference between them and results/unions except syntax. The below all express the same thing. Swift in fact uses the checked throws syntax. Result<T,E> fn() T | E fn() T fn() throws E fn() throws(E) -> T
- oompydoompy74 5mo ago[flagged]
- Quarrelsome 5mo agothanks for helping.
- adjejmxbdjdn 5mo agoI 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 5mo agoI 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
- adjejmxbdjdn 5mo agoSure. Maybe it was a skill Issue. I switched between dozens of similar codebases over a period of 3-4 years (pre AI) when I was consulting and did multiple projects in multiple languages (well, only 1 in rust). In my experience switching between the C# projects was always the worst. The codebase semantics diverged in ways I simply didn’t see in the Java/C++ codebases.
- Sharlin 5mo agoDiscriminated 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 5mo agook, 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 5mo agoI 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 5mo agoOk. 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.
- airstrike 5mo agoThey are so fundamental to the way I write code I can't imagine ever using a language that does not support them. "Make invalid states unrepresentable."
- arwhatever 5mo agoI might suggest that anyone who wants to make it concrete to go through the article https://fsharpforfunandprofit.com/posts/designing-with-types-making-illegal-states-unrepresentable/ https://fsharpforfunandprofit.com/posts/designing-with-types... while visiting https://dotnetfiddle.net https://dotnetfiddle.net and typing the code samples in, experimenting with what manner of changes and additions to the code cause the compilation to fail, and considering how you would leverage those abilities in your everyday development work. I think this would be even more powerful if you then come back and re-read some of the pro-Union comments in this very thread.
- andix 5mo agoI've never been confused by language features. Usually the architecture or extreme indirection of the code is the confusing part.
- zoogeny 5mo agoThis is a classic debate in programming, literally: 2001: "Beating the Averages" (Paul Graham) [1] 2006: "Can Your Programming Language Do This?" (Joel Spolsky) [2] Both of these articles argue for the thesis that programmers that have been deprived of certain language features often argue that they don't need those features since they are already comfortable working around the lack of said features. It's a fancy way of arguing: you don't know what you're missing because you've never had it. Or, don't knock it until you try it. Consider, is your argument a) I've never used it and don't see a need for it, or b) I've used it before and didn't get any benefit? 1. https://paulgraham.com/avg.html?viewfullsite=1 https://paulgraham.com/avg.html?viewfullsite=1 2. https://www.joelonsoftware.com/2006/08/01/can-your-programming-language-do-this/ https://www.joelonsoftware.com/2006/08/01/can-your-programmi...
- deleted 5mo ago[deleted]
- Quarrelsome 5mo agoI can already do functional programming like map/reduce in C# tho. Not sure what the LISP argument is. Spolsky was saying there's a perf benefit in there somewhere but I'm not seeing how unions give me that.
- zoogeny 5mo agoYou have at least two options: 1. Argue from ignorance. Never try unions in any other programming languages and completely disallow their use in C# codebases that you participate in. 2. Try them out and adopt an informed opinion. You may even choose to remain in ignorance until someone wastes their own time trying to convince you. But it isn't my job or desire to teach someone who won't put in the effort to learn for themselves.
- Quarrelsome 5mo agoits not your job to comment spitty replies either but yet you volunteer that time, when you could have been productive instead of whatever the fuck this shit is. My primary concern with this pattern versus exceptions is calling code can simply discard the resulting problem.
- bertylicious 5mo agoHave you considered trying them out (maybe in F#) to understand why they are so popular in many other languages?