Is your programming language unreasonable? | F# for fun and profit
As should be obvious, one of the goals of this site is to persuade people to take F# seriously as a general purpose development language.
But as functional idioms have become more mainstream, and C# has added functional capabilities such as lambdas and LINQ, it seems like C# is “catching up” with F# more and more.
So, ironically, I’ve now started to hear people say things like this:
“C# already has most of the features of F#, so why should I bother to switch?"*
“There is no need to change. All we have do is wait a couple of years and C# will get many of the F# features that provide the most benefits.”
“F# is slightly better than C#, but not so much that it’s really worth the effort to move towards it.”
“F# seems really nice, even if it’s a bit intimidating. But I can’t see a practical purpose to use it over C#.”
No doubt, the same comments are being made in the JVM ecosystem about Scala and Clojure vs. Java, now that Java has lambdas too.
So for this post, I’m going to stray away from F#, and focus on C# (and by proxy, other mainstream languages),<br>and try to demonstrate that, even with all the functional features in the world, programming in C# will never be the same as programming in F#.
Before I start, I want to make it clear that I am not hating on C#. As it happens I like C# very much; it is one of my favorite mainstream languages,<br>and it has evolved to be very powerful while being consistent and backwards compatible, which is a hard thing to pull off.
But C# is not perfect. Like most mainstream OO languages, it contains some design decisions which no amount of LINQ or lambda goodness can compensate for.
In this post, I’ll show you some of the issues that these design decisions cause, and suggest some ways to improve the language to avoid them.
(I’m now going to don my flameproof suit. I think I might need it!)
UPDATE: Many people have seriously misread this post, it seems. So let me be clear:
I am not saying that statically typed languages are “better” than dynamic languages.
I am not saying that FP languages are “better” than OO languages.
I am not saying that being able to reason about code is the most important aspect of a language.
What I am saying is:
Not being able to reason about code has costs that many developers might not be aware of.
Therefore, being “reasonable” should be one of the (many) factors under consideration when choosing a programming language, not just ignored due to lack of awareness.
IF you want to be able to reason about your code, THEN it will be much easier if your language supports the features that I mention.
The fundamental paradigm of OO (object-identity, behavior-based) is not compatible with “reasonability”, and so it will be hard to retrofit existing OO languages to add this quality.
That’s it. Thank you!
What is a “reasonable” programming language, anyway?
If you hang around functional programmers, you will often hear the phrase “reason about”, as in “we want to reason about our programs”.
What does that mean? Why use the word “reason” rather than just “understand”?
The use of “reasoning” goes back to mathematics and logic, but I’m going to use a simple and pragmatic definition:
“reasoning about the code” means that you can draw conclusions using only the information that you have right in front of you, rather than having to delve into other parts of the codebase.
In other words, you can predict the behavior of some code just by looking at it. You may need to understand the interfaces to other components, but you shouldn’t need to look inside them<br>to see what they do.
Since, as developers, we spend most of our time looking at code, this is a pretty important aspect of programming!
Of course, there is a huge amount of advice out there on how to do just this: naming guidelines, formatting rules, design patterns, etc., etc.
But can your programming language by itself help your code to be more reasonable, more predictable? I think the answer is yes, but I’ll let you judge for yourself.
Below, I’ll present a series of code fragments. After each snippet, I’m going to ask you what you think the code does. I’ve deliberately not shown my own comments so that you can<br>think about it and do your own reasoning. After you have thought about it, scroll down to read my opinion.
Example 1
Let’s start off by looking at the following code.
We start with a variable x that is assigned the integer 2.
Then DoSomething is called with x as a parameter.
Then y is assigned to x - 1.
The question I would ask you is simple: What is the value of y?
var x = 2;<br>DoSomething(x);
// What value is y?<br>var y = x - 1;
(scroll...