3 ms·
.NET now has a lot of functional stuff. It has a whole functional language (F#), that can natively interop with .NET libraries (even if they are written in C#)
by kumarvvr 5y ago
.NET now has a lot of functional stuff. It has a whole functional language (F#), that can natively interop with .NET libraries (even if they are written in C#)
C# itself has many functional constructs.
With the modern minimal APIs, you can create a single file web application servers, without ever creating any objects.
OOP is the bread and butter of .NET, just like Java.
- DaiPlusPlus 5y ago> C# itself has many functional constructs. -ish. You can't have true FP without a high level of referential-transparency, that's something the CLR doesn't support due to restrictions in the CLR's type-system, which in-turn restricts languages on-top of the CLR like C# and F# (and we see that in the limitations in the F# language). Back to C# though: Function-references are passed as strongly-typed delegate objects (which include a bound `this` reference), but there's no reification of function parameters: so there's no spread-operator for parameters, nor currying, nor equivalence of delegate-types. There are workarounds for most (but not all) of these issues, but it just results in the tedious writing of wrappers everywhere, which drives me mad. A trend with C# that I've noticed is that it gets a lot of cool features, but each cool new feature always has a wart on it somewhere. * User-defined implicit type conversion, but only between user-defined types, not between interfaces, and there's no in-box interface that expresses such a conversion for use as a generic constraint (i.e. we still need an `IConvertTo<T>`). * If you use interpolated strings you're forced to use CurrentCulture. You need to jump through a lot of hoops to use InvariantCulture or your own interpolation formatting logic (improved in C# 10, but still doesn't address the jump-through-hoops problem). * Generic type covariance/contravariance, but only for interface types, and when the type-arguments are reference-types. * Generic type constraints, except they don't participate in overload resolution. And so on...