If you haven’t used C# in a while (or ever!) you might share some of these common assumptions about the language and its framework:
It’s Microsoft’s version of Java. It’s not expressive like Ruby. It lacks functional features.
Although I’ve spent plenty of time heads down in the languages officially supported by COPIOUS (such as Ruby and PHP), the majority of my software engineering career has been spent within the .NET framework, building web and Windows applications in C#. Recently, I found myself in a discussion about the merits of C#, and its place in the developer’s toolkit.
While I’ll concede there may be partial truth to some of the assumptions about C#, many of the features introduced throughout the last decade made it a compelling and enjoyable language to work with. Extension methods, LINQ, excellent generic support, named/optional method arguments, asynchronous methods, and late static binding have managed to keep the language looking a little more like a poor-man’s Scala than a mere Java rip-off.
But what about functional features?
Functional programming has been a popular topic in the programming world, and here at COPIOUS as well. C# hopped on the functional programming bandwagon in 2007, and with its introduction of lambda expressions and other functional features such as tuples, it comes closer to a multi-paradigm approach than some might think.
Does it do currying on its own? No, but it does provide partial function execution, and one can write a curry function using the language tools available.
Does it provide super-easy immutability and list comprehensions like Scala or Erlang? No, not quite, but there are readonly fields, and LINQ.
The small set of functional features that were added to the language five years ago have brought big changes to the way C# looks, and are now found extensively throughout the core .NET libraries — most often in the form of anonymous functions used as lambda expressions.
So where does C# fit?
Although C#’s delegate provided a similar functionality, the introductions of the lambda expression, complete with type inference, in C# 3.0 changed the face of the language. (Lambda expressions essentially provide syntactic sugar to wrap closure-supporting anonymous delegates, which were added in C# 2.0). A C# programmer today will find methods that accept lambda expressions as parameters everywhere. This is a good thing. Not only do programmers get to write fewer lines of code, but the language also becomes more expressive, less confusing, and much more like some of the other popular language choices.
One thing I love about C# are the various features that have been introduced with each language release, often making the language more elegant and easy to write. Combining these functional features with the ubiquity of generics in modern C# gives us a language with little resemblance to the language introduced at the beginning of the century.
To say C# is a multi-paradigm language that includes functional programming may be pushing the envelope. But as new versions of the language emerge, expect to see more influences from other languages and programming trends.