Recently, I’ve been having a lot of conversations with a friend of mine about meta-programming, partly due to some development we are working on, and partly due to our coming PhD. Some of the time we incur in largely (perhaps irrelevant) philosophical ruminations about programming languages.
But today, he found a rather peculiar blog-post, where the author teases the readers arguing “Why learning Haskell/Python makes you a worse programmer”.
Why learning Haskell/Python makes you a worse programmer?
The author presents two claims to defend his thesis: a) Demotivation and b) Code Obfuscation. Considering demotivation, he states that he “(…) constantly find (himself) wanting to use idioms from these languages, or noticing how much less code (he would) be able to write if (he) was using one of these languages (…)”. Further, it notes that it finds “(…) C# code very ugly compared to both Python and Haskell (…)”. The conclusion, he remarks, “is to make me very depressed and demoralised. I feel like a human compiler, translating the Haskell or Python in my head into a language which is a whole level lower.”
In what comes to code obfuscation, the author believes that because “C# has begun to get some features that are more friendly to functional style programming”, the programmer “when faced with a very common situation” tends to try a “functional solution”. Adapting this “functional solution” to a language like C#, results in “writing such complex code — using such advanced features as anonymous delegates — when a simple loop would have sufficed”. The overall conclusion is “don’t bother improving yourself, unless you have the freedom to improve your environment accordingly.”
While I tend to sympathize with the author frustrations, I believe this to be a classic example of misunderstanding about programming paradigms and languages. In fact I’ll try to summarize my arguments on “Why learning Haskell/Python makes you a *better* programmer”.
The difference between Paradigm and Syntax
First and foremost one must understand the difference between paradigm and syntax. Each different paradigm usually results in a different algorithm. Though, the same algorithm can be expressed in different syntaxes, which depends on the language one’s using to implement. The fact that a certain syntax is less ugly to a programmer implementing a certain algorithm designed in a certain paradigm qualifies the expressiveness of a language. This expressiveness is dependent on the domain’s problem and the paradigm of the solution, so different algorithms (that solve the same problem) can make the same language seem very beautiful or very ugly.
Expressiveness in Programming Languages
A common metric used to quantify the expressiveness of a language is the number of code lines needed to implement a certain algorithm. It is very common to find advocates of every language, using as arguments single-liners to convince that her/his language is the best: “just compare this one-line quick-sort implementation in X to this 30 line implementation in Y”. This makes the reader believe that X is more expressive than Y, while not noticing that the algorithm paradigm used for X is the same as the native paradigm of X, while the opposite isn’t always true (e.g. see [1] [2] and [3]).
The “other side”
It’s also amusing to see many people learning functional languages, believing they are the other side, and putting C and C# (or Java) in the same bag. Why this happens? Because people tend to learn syntaxes and not paradigms. If a language has a syntax very close to another (like C, C++ and C#), they tend to believe that the paradigm is the same. Even worse, because they find that a certain syntax in a certain language produces expressive code, they incur in the pitfall of trying to apply the same paradigm in a different language (and, surprise! that language wasn’t designed to be expressive in that paradigm). I’ve seen this problem occur over and over, especially in people that already have some programming experience; how many times I’ve seen code written in Java which is plain old C in another syntax?… These authors don’t have a clue what Object-Oriented is all about, and I doubt they also have a clue what Functional Programming or Logic Programming is about too (somehow, Prolog and the Logic Paradigm tends to be forgotten).
Which is the best?
What is the solution? In portuguese we say “Cada macaco no seu galho”, which losely translates to “To each its own”. One must understand that there are several forces to be taken account when choosing a certain language to implement a desired solution. Most of the time this are related to infrastructure features (like available frameworks and tools). But an important force (most of the time marginalized) is related to the problem’s domain; I would argue that functional languages are very expressive in what comes to mathematical defined algorithms and that I would definitely choose C to implement a device-driver (don’t confuse the choice of expressiveness with performance) and SQL to define relational queries.
The author’s mistake, in my point of view, is trying to force-fit a solution in a paradigm that is not natural to the language in question (for the author’s sake, I know that he knows this, but not everyone understand this). Just because a language has the infrastructure to deal with certain paradigms (like C# 2.0 new functional-oriented features), this doesn’t mean the necessary syntax is there to make it expressive in that same paradigm; “while in Rome be Roman”.
What can we do?
One solution for the problem of expressiveness are Domain Specific Languages (DSL). DSLs try to solve this by extending/redefining the original syntax and semantic of a language to better express solutions designed for paradigms more closely related to the problem’s domain (consider LINQ and mathematical sets) while maintaining the concepts horizontal between syntaxes (which differ from scripting or embedded interpreters). DSLs aren’t just syntactic sugar (I will argue about this on a different post).
Why learning Haskell/Python makes you a better programmer?
So why does learning other languages (especially languages that implement other paradigms) makes you a better programmer? a) Because it teaches you different points of view and b) because it gives you the best syntax and semantic for a certain domain. Learning different languages don’t necessarily make you better in other languages. It makes you better in understanding and designing new algorithms, though. But most important, it should make you feel more decoupled from implementation details and more detached from syntax.
There is an analogy that I like to apply when people ask “Is it worth it?”. Scott Ambler, in his book The Object Primer, talks about the difference between the Specialist and the Generalist. He argues that while a specialist is a “Jack-of-all-trades and a master of none”, good developers should try to be generalists, as in a “Jack-of-all-trades and a master of few”.