1. Pursuing a "new language".
Basic philosophy tells us that new things are not necessarily "new things", but may be a retrogression of history. Facts have proved that many new languages are not as good as those that have existed for a long time. Face up to this fact, how many "new concepts" of modern languages do not exist in some of the oldest languages? Programming languages are like commodities, and every household is actually advertising. Most designs, including some concepts in the most "difficult" and "theoretical" languages, may be superficial and short-lived. If you can't see through the design of these things, you will be fooled by them. Excessive enthusiasm and excessive publicity often mean superficiality. Many language designers do not really understand the principle of programming language design, so they often make mistakes in design. But in order to promote their own language and system, they must talk big and carry out religious propaganda.
2. "Being is reasonable".
I remember a famous person saying, "There is no need for a language that can't bring new ways of thinking." He's quite right. Of all the languages in the world, which ones have brought new ways of thinking? Very few, actually. Most languages bring only chaos to the world. Some people may retort, "How can you say that language A doesn't need to exist? The library l I want to use is not supported by other languages, so I can only use A. "But notice that what he said is the" necessity "of existence.
It is illogical to regard the "fact" of existence as the "necessity" of existence. It's like if we didn't defeat Hitler in World War II, and now we are all his slaves, and then you say, "Hitler should exist because he supports us." Obviously there is something wrong with this logic, because if history goes the other way (that is, Hitler does not exist), we will live a free and happy life, so Hitler should not exist. It is the correct logic to compare the two possible consequences of the existence and non-existence of a thing and then make a judgment. According to this reasoning, if the poorly designed A language does not exist, then the better designed B language is likely to get more support, thus realizing or even surpassing the functions of the L library.
3. Pursuing "new functions".
Designers of programming languages always like to "invent" new terms and publicize them. Ordinary programmers often can't see that most of these "new concepts" actually have a profound and fashionable appearance, but they have no substantive connotation. Usually, just after learning one language A, another language B comes and says it has a new feature called XYZ. So you started learning B again, and so on. In the eyes of the industry, most of these so-called "new functions" are old wine in new bottles. Many people like this title when writing papers: XYZ: a novel method ... which caused an explosion of concepts, but no substantive progress was made. It can be said that this is the most fatal shortcoming of computer science.
4. pursue "small moves."
Many programming books like to show off some tricks to make the program look "short". For example, they will tell you what results "(i++)-(++i)" should get; Or examine the priority of operators, saying that parentheses can be reduced; Or tell you, "If there is only one line of code behind, you don't need curly braces", and so on. I don't know that most of these tips are actually the failure of programming language design or problems left over from history. What they bring is not clear thinking, but logical confusion and cognitive burden. For example, the++operator of C language appears because the computer memory used by C language designers is pitiful, and "i++" is obviously two characters less than "i=i+ 1", so they think it can save some space. Now we have no shortage of that memory, but the confusion and confusion brought by the++operator have been passed down. Now some of the latest languages also like to play this grammar trick. If you pursue these skills, you will often miss the essence.
5. For "specialized fields".
Many languages are nothing new. In order to occupy one side of the land, they claim to be suitable for a specific task, such as text processing, database query, Web programming, game design, parallel computing, or other specialized fields. But do we really need different languages to do these things? In fact, most of these things can be solved in the same common language, or slightly changed on the basis of the existing language. However, for various political and commercial reasons, different languages are designed to occupy the market. As far as learning is concerned, they are actually irrelevant, and the problem of "multilingual cooperation" they bring almost obscures their benefits. In fact, you can learn the essence of all these "specialized languages" from some well-designed common languages. I will recommend one or two such languages later.
I must point out that the above psychology is harmful not only to myself, but also to the whole industry. When people who are taught by these ideas enter the company, they will start to turn these once-feared things into dogmas and use them to screen new people, which will form a vicious circle.
How to master all programming languages
To be honest, I have expert opinions on almost all styles of programming languages. They are so simple in my mind that I am no longer a "supporter" of any language, including functional languages. But I have spent too much time exploring this road, and I hope to extract some "tips" that can help people reach this consensus in a short time. The specific details are enough to write a book, and I only make some preliminary suggestions here now.
1. Pay attention to "essence" and "principle".
Like all sciences, there are only a few essential principles of programming languages, but they can be used to construct many complex concepts. However, people often ignore the importance of simple principles and pursue the latest complex concepts after reading them in a hurry. They don't notice that most of the latest concepts can actually be combined with the simplest ones. However, a little knowledge of basic concepts leads them to fail to see the essence of those complex concepts. For example, one of the concepts is recursion. Many students in China only understand recursion in programs like the Tower of Hanoi, but they also have great misunderstandings about the efficiency of recursion, thinking that recursion is not as efficient as loop. In fact, recursion is much stronger than circular expression, and the efficiency is similar. Some programs, such as interpreters, are difficult to complete without recursion.
2. Implement a programming language.
The best way to learn to use tools is to make tools, so the best way to learn programming languages is to implement them. This does not need a complete compiler, just write some simple interpreters to realize the most basic functions. After that, you will find that you probably know how to realize all the new features of the language, not just at the user level. The fastest way to implement a programming language is to use a language like Scheme, in which code can be used as data. It allows you to quickly write a new language interpreter. There are some examples of interpreters I wrote in my GitHub (for example, this short code realizes Haskell's lazy semantics). You can refer to it if you are interested.
Several common language styles
Let me briefly talk about several common language styles and their problems. Note that the classification here is not in the strict sense, and some may overlap conceptually.
1. Object-oriented language
Facts show that the whole concept of "object-oriented" is basically wrong. Its popularity is due to the initial "software crisis" (God knows whether this crisis really exists). The original intention of the design is to separate "interface" from "implementation", so that the changes of the lower-level implementation will not affect the functions of the upper layer. However, the design of most object-oriented languages follows a fundamentally wrong principle: "Everything is an object." So that all functions must be placed in so-called "objects" and cannot be passed directly as parameters or variables. This often leads to the need to use cumbersome design patterns to realize things that are simple even for C language. In fact, the separation of "interface" and "implementation" does not require putting all functions into objects. Other concepts, such as inheritance and overloading, actually bring more problems than they solve.
The overuse of "object-oriented method" has begun to have a negative impact on the whole industry. Programmers in many companies like to copy some unnecessary design patterns mechanically, but in fact, they have not done anything good, just making the program long and difficult to understand. I have to point out that the book Design Patterns is the chief culprit of this great complexity. It's a pity that such a superficial, content-free, concept-stealing book has been praised as a classic by many people.
What about object-oriented languages with higher-order functions, such as Python, JavaScript, Ruby and Scala? Of course, with higher-order functions, you can express many things directly without using design patterns. However, due to the pernicious idea of design patterns, some programmers actually use complex design patterns in these languages that do not need design patterns, which makes people laugh and cry. Therefore, when studying, it is best not to use these languages to avoid unnecessary interference. Come back and use it when necessary, you can take its essence and discard its dross.