6 ms·
C# first introduced lambdas and LINQ in v3, back in 2007. It was the first mainstream OO language to really push a more functional/mixed-paradigm approach. Thi
by stupidcar 10y ago
C# first introduced lambdas and LINQ in v3, back in 2007. It was the first mainstream OO language to really push a more functional/mixed-paradigm approach.
This is definitely an area where Microsoft has lead the market, not followed it.
- louthy 10y agoThey may have been the first, and LINQ was (and is) a truly great feature (I'd love it if they'd expand the grammar, or allow computation expressions like F#); but the problem I've found with trying to do functional programming in C# is that there's no BCL support. Whereas F# has its functional prelude. I haven't spent much time with Scala, but I get the impression that a lot of the functional stuff is there by default (or at least easily accessibly via Scalaz) and therefore less inertia is needed to write functionally in Scala. Even with LINQ most C# programmers think it's just for querying databases or XML files, they don't realise they have built in monad semantics. I found that I'd have an immutable collections library over there, that wasn't aware of the Option type in that library over there. (So Map.Find(key) couldn't return an Option<V> for example - this makes composition more difficult). So although the language has been steadily going in the right direction, there has been less of a concerted effort on the library front. And therefore C# is still behind IMHO. This is something I've been trying to rectify, by essentially building a functional BCL [1]. I welcome the increased pace of functional features recently. Although sometimes it's frustrating seeing the direction they're going and wishing they'd get there much quicker (expressions everywhere, sum-types, record-types, better type inference). It's interesting that often C# is held up for its inability to do type-classes or ad-hoc polymorphism. But it is in fact possible with C# today [2] [3], and with zero cost (i.e. no reflection, additional memory allocations, or side-stepping of the type-system). It just causes a massive head-ache of manually provided generic arguments... [4] [5] I'd love it if the Roslyn team took some time to deal with the generic parameters inference story. It would help bring ad-hoc polymorphic types to C#, but it would just be awesome in general. [1] https://github.com/louthy/language-ext https://github.com/louthy/language-ext [2] https://github.com/louthy/language-ext/blob/type-classes/LanguageExt.Tests/TypeClassMonad.cs https://github.com/louthy/language-ext/blob/type-classes/Lan... [3] https://github.com/louthy/language-ext/blob/type-classes/LanguageExt.Tests/TypeClassMonoid.cs https://github.com/louthy/language-ext/blob/type-classes/Lan... [4] 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... [5] https://github.com/louthy/language-ext/blob/type-classes/LanguageExt.Core/DataTypes/Option/Option.cs#L780 https://github.com/louthy/language-ext/blob/type-classes/Lan...
- plaguuuuuu 10y agoThat is really cool. I'm definitely going to try it out.
- haimez 10y agoArguably, that doesn't count as type classes because it REQUIRES call-site awareness of the implementation. This makes it fully ad-hoc and fully impractical as a useful abstraction. At that point you might as well call a static method without polymorphic parameter types, because it's just as (in)convenient and 100% more readable to the developer maintaining the project after you move on to a better programming language.
- louthy 10y ago> Arguably, that doesn't count as type classes because it REQUIRES call-site awareness of the implementation Yes. I should have stated it's not real type-classes, but it is real ad-hoc polymorphism, which does get you much of the way there. The type-system won't infer the instance, you need to specify it manually. That doesn't make the solution less powerful from a generic programming point-of-view (if anything it makes it more powerful, because you can provide the instance you want to use); however it does make it more awkward to use. > and fully impractical as a useful abstraction. I disagree with this though. Finally being able to define a numeric type, or make types into real monads where a function can declare a constraint that requires an argument to be a monad is a good thing. > At that point you might as well call a static method without polymorphic parameter types From what I can tell, you're thinking of just the call site, but a whole call stack can carry through the constraint, and therefore the call site doesn't need the concrete implementation, it just needs a type that is constrained to the 'type class' (interface). The call site wouldn't know the type of the static method to call in your case. For example with a numeric type: public static T Add<T>(T lhs, T rhs) => // what static method can you call here? If you don't use polymorphic types, then you're not writing generic code, which is what this is for: public static class Math { public int Add(int lhs, int rhs) => lhs + rhs; public double Add(double lhs, double rhs) => lhs + rhs; public float Add(float lhs, float rhs) => lhs + rhs; public decimal Add(decimal lhs, decimal rhs) => lhs + rhs; } What about when you forget: BigInteger, short, byte, long, etc. But with the method I explained above: public interface Num<A> { A Add(A lhs, A rhs); } public struct NumInt : Num<int> { public int Add(int lhs, int rhs) => lhs + rhs; } public struct NumBigInt : Num<BigInteger> { public BigInteger Add(BigInteger lhs, BigInteger rhs) => lhs + rhs; } etc. Any code that works with numeric values can then be written once. I'm sure many C# programmers over the years have cursed over having to write N variants of something that should work with IArithmetic, or INumber, or something similar. This gets around that problem (and without causing any boxing either). So, personally, I think it has value. Even if it's only needed rarely. > because it's just as (in)convenient and 100% more readable to the developer maintaining the project after you move on to a better programming language. My library isn't about the mindset of programmers who are stuck in OO-land with all the conservative nonsense that goes along with it. So although I agree there's a learning curve, I don't think this is too problematic for those who want to write truly generic code. By the way, Microsoft are experimenting with this technique[1] (and new grammar) for future versions of C#. Whether it makes it or not, who knows, but I think it would be a super valuable feature for C#. [1] https://github.com/CaptainHayashi/roslyn/blob/master/concepts/docs/concepts.md https://github.com/CaptainHayashi/roslyn/blob/master/concept...
- addicted 10y agoMS's Scala equivalent would be F# which was out in 2005. This is just adding more functional programming aspects to their dominant language.
- bigdubs 10y agoPedantic comment incoming; F# is more of an ML implementation.
- Rapzid 10y agoPedant; you're missing the compare for the contrast.
- seanmcdirmid 10y agoScala is more OO than F# or even C#, in that it has very advanced OO features that are not seen in other OO languages. OO in F# is more about interop.
- azth 10y agoWhat sort of advanced OO features are you referring to?
- seanmcdirmid 10y agoTraits as full fledged mixins (including state!) are my favorite feature. No other language has this with static typing.
- deleted 10y ago[deleted]