11 ms·
Throw expressions are particularly welcome. I'd previously dealt with that issue by creating a static method that returned the expected type, but just threw an
by louthy 10y ago
Throw expressions are particularly welcome. I'd previously dealt with that issue by creating a static method that returned the expected type, but just threw an exception [1][2]
I'm not sure it's explicit in the blog, but it seems the deconstructor will be useful for pattern-matching using 'is'.
Tuples. Yay! Finally!
Pattern-matching-switch-statement: Not an expression. That's a bad call. We have expression based ternary, throws, method bodies, and LINQ; switches are the last and most painful omission.
Local functions: Fantastic for libraries like mine, which is trying to bring functional programming to the C# world, but takes a hit with the allocation of delegates for common operations [3] It should be a boon for anything LINQ based (implementations, rather than usage).
Return by ref and out parameters: I'd be happy if they just removed them from the language. Ugly, error magnets.
All in all, good progress. Hopefully they can make more progress on facilitating expression-based programming, and bring in record types for the next release. The pain of creating immutable types is truly tedious. And I'd desperately like to see partial generic parameter specifying (for when one of the generic arguments can't be inferred by the type-system, so you then end up having to specify them all).
[1] https://github.com/louthy/language-ext/blob/master/LanguageExt.Core/Prelude.cs#L209 https://github.com/louthy/language-ext/blob/master/LanguageE...
[2] https://github.com/louthy/language-ext/blob/master/LanguageExt.Core/Prelude.cs#L182 https://github.com/louthy/language-ext/blob/master/LanguageE...
[3] https://github.com/louthy/language-ext/blob/type-classes/LanguageExt.Core/TypeClasses/Monad/Monad.Prelude.cs#L70 https://github.com/louthy/language-ext/blob/type-classes/Lan...
- moogly 10y agoFully agreed on pattern matching not being an expression. I really dislike that syntax overall. I get the reluctance to introduce new keywords (though this did introduce 'when', but I suppose it's contexual at least), but trying to shoehorn pattern matching into the, um, let's be nice and call it "venerable", old switch/case does not look very ergonomic at all. And I don't know about you, but I rarely switch over polymorphic types these days, I mostly switch over values, so the pattern matching overall is way less useful to me without records/discriminated unions. I guess you can't really remove 'ref' and 'out' due to interop. Maybe the ref returns stuff will be nice if we get more performant string/array views in the next version, and I do like the inline 'var out'. I also want type inference for field declaration+initialization, but I think Eric Lippert once explained why that was a difficult problem to solve, albeit I can't remember the reason.
- louthy 10y agoI think switch could have been made into an expression very easily by following the lead of lambdas and method-body expressions, namely the => arrow. var area = switch ( case Line l => 0; case Rectangle r => r.Width * r.Height; case Circle c => Math.PI * c.Radius * c.Radius; default: throw new ApplicationException(); ) That 'feels' to me to be consistent with the expression approach taken elsewhere, whilst making it clear to anybody used to seeing the statement based switch that it's different. > so the pattern matching overall is way less useful to me without records/discriminated unions. I agree partially. I think it's possible (I'll investigate tomorrow) to provide an 'is' operator override. So for example in my implementation of Option<T> [1] (which would usually be a sum-type of Some(x) and None, I instead use a struct (to remove a 3rd state of null). With the 'is' operator I'm hoping to do this: public static class Some { public static bool operator is(Option<T> option, out T value) { value = option.Value; // Value is internal return option.IsSome; } } switch(option) { case Some x: ...; break; default: ...; break; } I'm not sure if I can do this: public static class None { public static bool operator is(Option<T> option) { return option.IsNone; } } switch(option) { case Some x: ...; break; case None: ...; break; } So although it doesn't solve the general need for sum-types and record-types, it should hopefully facilitate some of the common use cases. Agreed about ref and out; I understand their purpose, I just despise them with a passion. Their whole syntax and ickyness makes me feel queesy. The inline var out feels like an imbalanced expression. They're clearly more useful now, but they still feel odd. [1] https://github.com/louthy/language-ext/blob/master/LanguageExt.Core/Option.cs#L24 https://github.com/louthy/language-ext/blob/master/LanguageE...
- Locke1689 10y agoRegarding switch-as-expression -- the semantics of pattern matching as an expression can be subtle, especially when paired with nullability, so I think there's more support for introducing a new "match" expression that does what you describe. Switch is more of an effort to integrate patterns in the way C# is used right now.
- snarfy 10y agoOf all the new features, ref return leaves me scratching my head. I agree ref and out should go away. Adding more support for ref will only increase its usage when it should be deprecated.
- naasking 10y agoWhy not support more safe ref/out uses? I don't see any need for them to go away. You're already disincentivized from using them due to the syntactic annotations required and they aren't compatible with standard delegate parameter types. So if you are using ref/out, you actually need them for some reason (likely performance-related).
- int_19h 10y agoIt shouldn't be deprecated any more so than "unsafe" and "stackalloc". It's a great advanced tool for perf-sensitive code - not something you should reach by default, but something to keep in mind when firing up that profiler. CLR supported the concept since 1.0. Surfacing it in C# has been long overdue, and makes it possible to write more low-level stuff without having to go to C++.
- naasking 10y ago> Return by ref and out parameters: I'd be happy if they just removed them from the language. Ugly, error magnets. I disagree. Firstly, more high-performance non-allocating code can now be written safely instead of dropping down into unsafe languages. Secondly, ref and out parameters are address types, which the CLR and C# need to properly handle to support value types/structs.