From translator
This is a free translation of an article about why people are afraid of functional languages, there is irony and humor, for those who can and likes to read the English original here .
About the author
I am a developer and architect of a British non-software company. I have 20 years of experience in various fields from high-level UX / HCI to low-level database implementations.
Despite the fact that I use C # in my daily work, I wrote industrial code in many languages, my favorite are Smalltalk, Python and most recently F # (that's why I created this site ).
Deliberations about what I do not understand
Are you tired of all the hype around functional languages? Me too! I will state on this occasion several reasons why reasonable people, like you and I, should stay away from it.
')
I’ll explain a little bit: when I say "a statically typed functional programming language," I mean languages ​​that support type inference by default and so on. In practice, this means Haskell and the ML language family (including OCaml and F #).
Reason 1. I do not want to follow the latest trends.
Like most programmers, I am conservative and do not like to learn new things. Actually, that's why I chose a career in IT.
I do not give in to mass hobbies simply because all the “tough guys” do it, at first I wait until the thing matures, and I can see some perspectives.
For me, functional programming is still too short a time to convince me that it is here to be serious and for a long time.
Yes, I believe that some pedants will argue that
ML and
Haskell exist almost as many as the old favorites of Java and PHP, but I heard about Haskell quite recently, so this argument is completely unconvincing.
Let's look at a newbie in this family:
F # . Lord, he is only 7 years old! Of course, this may be enough time for a geologist, but in the Internet era, 7 years is just a blink of an eye.
Thus, I would definitely be cautious and wait a few decades to see whether functional programming will remain or not meet expectations.
Reason 2. I get paid for lines of code.
I don’t know about you, but the more lines I wrote, the more productive I feel. If I can stamp 500 lines per day, then the work is done well. My commits are big and my boss can see that I was busy.
But when I
compare code written in a functional language with a good old school C-like language, then I see so little code that it scares me.
Just see what I mean, here is the code written in a familiar language:
public static class SumOfSquaresHelper { public static int Square(int i) { return i * i; } public static int SumOfSquares(int n) { int sum = 0; for (int i = 1; i <= n; i++) { sum += Square(i); } return sum; } }
Now compare with this:
let square x = x * x let sumOfSquares n = [1..n] |> List.map square |> List.sum
17 lines against only 2 lines. Now
imagine the difference if this is multiplied by the size of the project.
If I used this, my productivity would drop dramatically. Sorry, but I can not afford it.
Reason 3. I love braces.
And one more thing. What happens to all these languages ​​that get rid of curly braces? How can they be called real programming languages?
I will show you what I mean. Here is a sample code with familiar curly braces.
public class Squarer { public int Square(int input) { var result = input * input; return result; } public void PrintSquare(int input) { var result = this.Square(input); Console.WriteLine("Input={0}. Result={1}", input, result); } }
But similar code, only without curly brackets.
type Squarer() = let Square input = let result = input * input result let PrintSquare input = let result = Square input printf "Input=%i. Result=%i" input result
Look at the difference! I do not know about you, but something bothers me in the second example, as if something important is missing here.
To be honest, I feel a little lost without braces.
Reason 4. I love to see explicit types.
Supporters of functional languages ​​argue that type inference makes code cleaner, not letting you keep it cluttered with type definitions all the time.
Actually, by the way, I want to see type declarations. I feel embarrassed if I do not know the exact type of each parameter. This is why
Java is my favorite language.
Here is the signature of the function of some ML-like code. Type definitions are not required, and everything is displayed automatically.
let GroupBy source keySelector = ...
And here is the function signature for similar code in C #, with explicit type definitions.
public IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>( IEnumerable<TSource> source, Func<TSource, TKey> keySelector ) ...
Maybe I'm in the minority, but I like the second version much more. For me it is important to know that the function will return the type
IEnumerable<IGrouping<TKey, TSource>>
.
Of course, the compiler will make a type check for you and warn you if it detects a type mismatch. But why let the compiler do this work if your brain can do it?
Well, I admit that if you use generics, lambdas, functions that return functions and all these newfangled things, then yes, your type definitions can really become overly complex and confusing. And it becomes very difficult to enter them correctly.
But I have an easy solution for this - do not use generics and do not pass functions anywhere, your signatures will become much easier.
Reason 5. I like to fix bugs.
I like nothing like hunting nasty bugs. Well, if the bug is in production, then this is even better, because at the same time you will become a hero when you fix it.
But
I read that in programs on statically typed functional languages ​​it is much more difficult to prevent a bug. Here is a bummer.
Reason 6. I live in a debugger.
By the way, about fixing bugs, I spend a significant part of my day in the debugger, step by step executing the code. Yes, I know, I should use unit tests, but is it easier said than done? It is so?
In any case, it is obvious that if your code on a statically typed functional language is compiled,
then it usually works .
I said that you have to spend a lot of time to align the types, but when this is done and the code is successfully compiled, there is nothing to debug. Well, what's the fun?
This reason leads me to the next ...
Reason 7. I don't want to think about every little thing.
Check types, make sure everything is in order, it all sounds so tiring to me.
In fact, I heard that you are forced to think about all possible boundary cases, and about all possible errors caused by incorrect input data, and in general about everything that can go wrong. And you have to do all this at the beginning, you can not be lazy and put it all aside for later.
I much like to get the program completely (well, almost completely) working according to a positive scenario (where all possible errors are not taken into account), and only then fix bugs as they appear.
Reason 8. I like to check for null.
I am very conscientious doing
checks for null in each method. It gives me great satisfaction, I know that as a result my code is completely bulletproof.
void someMethod(SomeClass x) { if (x == null) { throw new NullArgumentException(); } x.doSomething(); }
Haha I was just joking. Of course, I cannot embed null checks everywhere, otherwise I would never have finished any real project.
In addition, for my practice, I only once encountered a serious problem caused by a NullPointerException. And the business lost not so much money, in the course of a few weeks that I spent searching for a problem. So I'm not sure what this is really a
necessary thing .
Reason 9. I apply design patterns everywhere.
I first read about design patterns in
the Head First Design Patterns book (which for some reason is referred to as the “Gang of Four Book”, but I'm not sure why), and since then I have always diligently used them to solve any problems. I am sure that my code after that looks serious, "enterprise" and this impresses my boss.
But I do not see any references to patterns in functional design. How can I do anything useful without using Strategy, Abstract Factory, Decorator, Proxy and everything else?
Perhaps functional programmers do not know about templates?
Reason 10. Too much math.
Here is the code to calculate the sum of squares. This recording method is too difficult to understand because of all these strange characters.
ss=: +/ @: *:
Oh sorry! I was wrong, it was
code on j .
But then I heard that functional languages ​​use strange characters like
<*>
and
>>=
, or incomprehensible concepts like "monads" and "functors".
I don’t know why functional programmers couldn’t stick to things already known to me, such obvious ones as characters like ++,! = And light concepts like “inheritance” and “polymorphism”.
Total. I do not understand this
You know, I do not understand this. I do not understand how functional programming is useful.
I really want someone to just show me the
real benefits on one page , instead of filling me with information.
Update: Ok, now I read the article "all you need to know on one page." But it is very short and simple for me.
All the same, I'm looking for something a little deeper,
something with which I
could work productively.
And no, don't tell me that I should read the
manuals ,
play with examples, and write my own code. I just want to look, without doing all this.
I do not want to change
my thinking , just to learn a new paradigm.
Comments of the author to the articleFor those who have problems with humor: this article should not be taken seriously.
For those who think I'm exaggerating or troll. Everything in this article is based on what I read or personally heard from other people (only with a slight exaggeration). I simply made explicit what was implicit in their reaction.
I’ll also explain that I’m not trying to be a snob or gnome for those who prefer not to use functional programming. People can use the tools they like. And there are many good reasons not to use functional languages, the same reasons that I cited are not related to this. I come across such defensive and irrational "arguments" all the time, and they should not be taken seriously.
Some prerequisites for each item:
Reason 1: "fashion." I can not say how many times I heard it. Please read a little about the history of computer science. “I am conservative and do not like to learn new things. Actually, that's why I chose a career in IT. ”I thought it should be funny. Okay.
Reason 2: "pay for the lines of code." Nobody said this directly, but if you look at any discussion, say, Python vs Java, some people are definitely more comfortable writing long and boring code.
Reason 3: “braces”. This is not about braces as such. Many people argue that the absence of curly braces makes the code unreadable, and in general
they are attached to them . Here is a
comment on this article itself , which shows my point of view.
Reason 4: "I like explicit types." Based on real comments
Reason 5: “I like to fix bugs” and reason 6: “I live in a debugger”. Again, no one said this directly, but a poor understanding of static code analysis tools speaks of this. People are hard to make even unit tests write. I think
intermittent reinforcement plays an implicit role in this behavior.
Reason 7: "I do not want to think about every little thing." None of us do that. That is why we must use tools that prevent us from being lazy. Otherwise, everything could end for you as one of the stories with
The Daily WTF .
Reason 8: "I like to check for null." Read any discussions about the usefulness of
optional types and soon you will find people saying that checking for null is not a problem.
Reason 9: "design patterns everywhere." Almost literally. Alas.
Reason 10: "too much math." Another common reason, and to some extent I agree (see
my request on this site ). But whether you like it or not, the theoretical part of computer science is very important.
SQL is based on theory.
Lambdas are based on theory. Algorithms for sets,
graphs ,
encryption, and everything else is also based on theory. The number of
mathematicians who
contributed to
computer science is huge.
For practical use of SQL, for manipulating sets, you do not have to know math in depth. In fact, the “mathematics” which you should study for functional programming is not much more complicated than the principles of SOLID in OOP. It's just different things.
Total. I know that learning functional programming is difficult, and it requires some changes in how you think about code. That's why I made
this site to help those who are curious and who want to learn.
And if you don’t want to learn something new, well, that’s good too.
Just please do not reject something that you have never tried based on flimsy arguments, or you can end up like
this guy .