It is not impossible to master all programming languages.

Source: Internet
Author: User
Tags ocaml
Learning programming languages is the only way for every programmer. However, there are too many programming languages in the world, each of which is known as having the latest "features ". So the programmer's annoyance is that he always needs to learn all sorts of strange languages and must keep up with the "trend"; otherwise, he will be afraid of being eliminated by The Times. As a programmer, I am deeply aware of the root cause of this psychology. In programming languages, there is actually a very simple, permanent principle.

This article was once called "The choice of programming languages for Beginners", but later I found that the opinions provided here are not only for beginners, but may even be incomprehensible to beginners. As I observed during my internship at Google, many senior programmers who have been writing programs for decades may not understand the principles mentioned here. So I changed the question and added new content. I hope it will be helpful to both the novice and veteran.

Author /? Wang Yin (do you remember the doctor Wang Yin who dropped out of Tsinghua? XD)

Learning programming languages is the only way for every programmer. However, there are too many programming languages in the world, each of which is known as having the latest "features ". So the programmer's annoyance is that he always needs to learn all sorts of strange languages and must keep up with the "trend"; otherwise, he will be afraid of being eliminated by The Times.

As a programmer, I am deeply aware of the root cause of this psychology. In programming languages, there is actually a very simple, permanent principle. Once you see them, you can grasp all the programming languages once and for all, instead of simply seeing the trees disappear from the forest. I want to write a book trying to explain the fundamental principles of programming languages (that is, computer science) in the simplest way, so that people can grasp the essence of all programming languages in a very short time. However, before I finish it, I would like to give some suggestions and reference books.

Misunderstandings about programming languages

People who learn programming languages often have the following psychology, so that they may feel that they can't finish learning things, or embark on the wrong path. I will give a brief analysis of these Psychology, hoping to eliminate some doubts.

1 .? The pursuit of "new language ".

The basic philosophy tells us that new things are not necessarily "new things", but they may be historical regresses. Facts have proved that many new languages are not as long as they existed. Let us face this fact. how many "new concepts" of modern languages do not exist in the oldest languages? The language of a program is like a commodity. every product is actually advertising. The vast majority of designs, including the concepts in some of the most "difficult" and "theoretical" languages, may be superficial and short-lived. If you cannot understand the design of these things, you will be blinded by them. Excessive enthusiasm and publicity often mean superficial. Many language designers do not really understand the principles of programming language design, so they often make repeated mistakes made by the people before. However, in order to promote their own language and system, they must speak out and conduct religious propaganda.

2 .? "Existence is reasonable ".

I remember a celebrity saying, "there is no need to bring new ways of thinking ." He is quite right. There are so many languages in the world. which of them bring new ways of thinking? In fact, there are few. Most languages bring chaos to the world. Someone may argue: "How can you say that language A does not have to exist? The database l I want to use. it is not supported in other languages and can only be ." But note that he is talking about the "necessity" of existence ". If you take the existing "fact" as the "necessity" of existence, the logic will be disordered. Just like if we failed to defeat Hitler in the second world war, and now we all made his slaves, then you said, "Hitler should exist because he has supported us ." Obviously, this logic is wrong, because if history goes another 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 existence and absence of one thing and then make a judgment. According to this reasoning, if A poorly designed language A does not exist, A better language B may be more supported to achieve or even surpass the functions of the L Library.

3 .? The pursuit of "New Features ".

Programmers always like the new term "invention" and hype. Ordinary programmers often don't see it. most of these "new concepts" actually have profound and fashionable appearances, but have no substantive connotation. It is often the first time I learned A language, and then came to another language B, saying that it has A new feature called XYZ. So you start learning B again. From the perspective of insiders, most of these so-called "new features" are new bottled old wines. Many people like the title XYZ: A Novel Method for.... This led to the explosion of concepts, but there was no substantial progress. It can be said that this is the most fatal shortcoming of computer science.

4 .? The pursuit of "tips ".

Many programming books like to show off some tips to make the program appear "short ". For example, they will tell you what results should be obtained from "(I ++)-(++ I)", or hold operators to priority, so that parentheses can be left blank; the other is to tell you that "if there is only one line of code behind it, you can leave no curly brackets", and so on. I don't know these tips. In fact, most of them are the failures of programming language design or historical issues. What they bring is not a clear idea, but a logical disorder and a burden of cognition. For example, the ++ operator of C language appears because the computer memory used by C language designers is small and poor, "I ++" is obviously two characters less than "I = I + 1", so they think it can save some space. Now we don't need any more memory, but the confusion and confusion brought about by the ++ operator has been circulated. Currently, some of the latest languages also like to play this syntactic trick. If you are pursuing these tips, you will not be able to grasp the essence.

5 .? For "specialized fields ".

Many languages have no new things. in order to occupy the land of one party, they claim that they are suitable for a specific task, such as text processing, database query, WEB programming, game design, and 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 using the same generic language, or a small change based on existing languages. However, for political and commercial reasons, different languages are designed to occupy the market. As far as learning is concerned, they are irrelevant, and the "multi-language collaboration" problem they bring about almost masks the benefits they bring. In fact, from some well-designed general languages, you can learn the essence of all these "specialized languages. I will recommend one or two of these languages later.

I must point out that these psychology are not only harmful to myself, but also very harmful to the entire industry. When people who are taught by these ideas enter the company, they will begin to turn the things they feared into dogmas to screen new people, leading to a vicious circle.

How to master all programming languages

To be honest, I have expert opinions on almost all programming languages. They are so simple in my mind that I am no longer a "supporter" of any language (including functional language ". However, I spent too much time exploring this path. I hope that some "tips" can help people achieve this general understanding in a short time. The specific details are enough to be written into a book. I will only give some preliminary suggestions here.

1. focus on "essence" and "principle ".

Just like all science, there are only a few of the most fundamental principles of programming language, but they can be used to construct many complicated concepts. However, people tend to ignore the importance of simple principles. they will pursue the latest and complex concepts after seeing them in a hurry. They did not notice that most of the latest concepts can be combined with the simplest ones. A half-understanding of the basic concepts makes them unable to see the essence of those complex concepts. For example, one of the most important concepts is recursion. In China, many students only focus on the procedures such as qingta, and misunderstand the efficiency of recursion. They believe that recursion is efficient without loops. In fact, recursion is much more powerful than loop table, and the efficiency is almost the same. Some programs, such as interpreters, cannot be completed without recursion.

2. implement a program language.

The best way to learn to use a tool is to make it, so the best way to learn a programming language is to implement a programming language. This does not require a complete compiler. Instead, you only need to write some simple interpreters to implement the most basic functions. Then, you will find that new features in all languages are probably aware of how they can be implemented, not just at the user level. The quickest way to implement a programming language is to use code like Scheme that can be used as data. It allows you to quickly write new language interpreters. My GitHub contains some examples of interpreters I have written (for example, this short code implements the lazy semantics of Haskell). If you are interested, refer to it.

Several common languages

Below I will briefly discuss several common style languages and their problems. Note that the category here is not strictly academic, and some may overlap in terms of concept.

1. object-oriented language

Facts show that the entire concept of "object-oriented" is basically false. It is popular because of the original "software crisis" (heaven knows if this crisis exists ). The original intention of the design is to separate the "interface" from "implementation" so that the changes made to the lower layer do not affect the upper layer functions. However, most object-oriented language designs follow the principle of a fundamental mistake: "Everything is an object )." So that all functions must be placed in the so-called "object", so that they cannot be directly transmitted as parameters or variables. This leads to the need to use tedious design patterns to achieve things that are even straightforward for the C language. In fact, the separation of "interface" and "implementation" does not need to put all functions into the object. Some other concepts, such as inheritance and overloading, actually bring about more problems than they solve.

The over-use of the "object-oriented method" has begun to play a negative role in the industry. Programmers in many companies prefer to stick to unnecessary design patterns. In fact, they have not done any good things, but it makes the program lengthy and difficult to understand. I have to point out that the book Design Patterns is the culprit of this huge part of complexity. Unfortunately, books that are so superficial, have no content, and have stolen concepts are regarded as classic by many people.

So how do we look at object-oriented languages with high-level functions, such as Python, JavaScript, Ruby, and Scala? Of course, with higher-order functions, you can simply express a lot of things without using design patterns. However, due to the virus of design patterns, some programmers have adopted tedious design patterns in these languages that do not require design patterns, making people laugh. Therefore, when learning, it is best not to use these languages to avoid unnecessary interference. When necessary, you can use them again to get the essence and get rid of the dregs.

2. what is a low-level procedural language?

Is it better to use a "low-level language" like C? Not actually. Many people advocate C, because it can bring people closer to the "bottom layer", that is, close to the expression of the machine, which means it is faster. There are actually three problems:

  • Is it good for beginners to approach "bottom layer?
  • What does "fast language" mean?
  • Is the language close to the underlying layer fast?

The answer to the first question is No. In fact, the most important idea of programming is the high-level semantics (semantics ). Semantics constitutes a concern of people and an algorithm for solving them. The specific implementation (implementation), such as an integer expressed in several bytes, is important, but not crucial. If we take implementation as the main goal of learning, we will put it upside down. Because implementations can be changed, but the essence they Express will not change. So many people find that what they learn will become obsolete soon. That is because they are learning not the essence, but the concrete implementation.

Second, speaking of the language's "speed" is actually an empty talk. Only responsible for languageDescriptionA program, but the speed of running the program, in fact, is mostly not dependent on the language. It mainly depends on 1)Algorithm?And 2)Compiler quality. The compiler and language are basically two things. A language can have many different compiler implementations, and the quality of the code generated by each compiler may be different. Therefore, you cannot say "A is faster than B ". You can only say "the code generated by the X compiler of language A is more efficient than the code generated by the Y compiler of language B ". This is almost equivalent to nothing, because B may have another compiler, making it generate faster code.

Let me give you an example. Historically, the Lisp language has the reputation of "turtle speed. Some people say that "the Lisp programmer knows the value of everything, but does not know the cost of anything". this is what we talk about. However, this is a long time ago. modern Lisp systems can compile very efficient code. For example, the commercial Chez Scheme compiler can compile itself within five seconds, and the compiled target code is very efficient. Its implementation is really amazing because its author R. Kent Dybvig is almost independent of any existing software and design. This compiler starts from the original parser to macro extension, semantic analysis, register allocation, various optimizations ,...... All the time until the assembler and function library are written by him. It can directly compile the Scheme program into machine commands of multiple processors without any third-party software. Some of its internal algorithms are actually much more advanced than open-source LLVM. However, due to commercial software, these algorithms have never been published as confidential.

Other functional languages can also generate efficient code, such as OCaml. In a summer program language class, Professor Robert Constable of Cornell told a story that they re-implemented a system using OCaml, the results show that the implementation of OCaml is 50 times faster than that of the original C language. After the group in C language optimized the algorithm multiple times, the OCaml version was several times faster. The reason is actually two reasons. The first reason is that functional languages free programmers from the underlying details so that they can quickly implement and modify their own ideas, so they can quickly find better algorithms. The second reason is that OCaml has an efficient compiler implementation so that it can generate good code.

From the above example, you may have seen that the language close to the underlying layer is not necessarily fast. This is because the compiler can actually have a very advanced "intelligence", or even surpass the underlying optimization that anyone can achieve. However, the compiler has not yet developed to the point where humans can be used to create algorithms. So what people need to do now is to design and optimize their own high-level algorithms.

3 .? Advanced procedural language

Early on, the first programming class for Chinese computer students was Pascal. Pascal is a good language, but many people didn't realize it at the time. In my freshman year, my Pascal teacher said to us, "Our school is too backward in teaching. Other schools have started to teach C or C ++, and we are still teaching Pascal ." Now that I really understand the design principles of the programming language, I feel that Pascal is a better language than C and C ++. It not only frees people from the underlying details, but does not have the shackles of object-oriented thinking. It also contains some features of functional languages (such as nested function definitions ). However, due to similar misunderstandings and misdirection, almost no one has ever used a language like Pascal. This is not a pity, because its essence actually exists in functional languages such as Scheme. Scheme also has a value assignment statement, so it essentially contains all Pascal functions. Therefore, the current functional language that contains the value assignment statement can be considered as an "improved version" of the advanced procedural language ".

4 .? Functional language

Functional languages are relatively the best designs today, because they not only focus on algorithms and solve problems, but also have no restrictions on the thinking of object-oriented languages. However, it should be noted that not every functional language has good features. Their supporters often refer to shortcomings as advantages. as a result, they are still put on unnecessary shackles. For example, OCaml and SML, because there are many immature designs in their type systems, you need to remember too many unnecessary restrictions.

Many people advocate "pure functional" languages (such as Haskell and Clean), and strongly oppose other languages with "value assignment" statements (such as Scheme and ML ). The basis is actually untenable. If you have written a functional language compiler, you will understand how to translate a pure functional language into machine commands. These advanced compiler transformations (such as CPS and ANF) actually reveal the essence of pure functional language. In fact, they are essentially different from the language with a value assignment statement, but since there is no value assignment statement, some things must be implemented in an easy way. Rational use of the assignment of local variables or arrays makes the program simpler, easier to understand, and more efficient.

5 .? Logical Language

Logical language (such as Prolog) is a new idea that surpasses functional language, so special training is required. A program written in a logical language can run in reverse mode. A program written in a common program language, if you give itInput, It will give youOutput. However, a logical language is very special. if you give itOutputIt can run in turn, giving you all possibleInput. In fact, through a very simple method, you can smoothly convert the program from the function type to the logic type. However, a logical language generally runs in reverse mode only when it is "pure" (that is, there is no complicated assignment operation. Therefore, it is best to start with a functional language to learn a logical language. after understanding basic functional programming skills such as recursion and pattern matching, let's look at Prolog, logic-based programming is much simpler.

Start from

But learning programming always starts with a certain language. Which language? In fact, each language has its own problems, so that in my future book, it will use a very simple language that contains the essence of all languages, but does not have anything redundant. But before I finish this book, I 'd like to recommend one or two ready-made languages.

From my point of view, I can first get started with Scheme, and then learn some Haskell (but not all), and then others will bypass the class. You don't need to learn all their details, but you just need to learn the best part. All remaining details will be easily filled in actual use. I will discuss what is the essence and what is the beginning that is not necessary to learn.

The first step of getting started from Scheme (rather than Haskell) is as follows:

  1. Scheme does not have a static type system like Haskell ). It doesn't mean that static types are not good, but I have to say that static types such as Haskell are far from being developed so that they can be fully written.Things Nature. For example, some important concepts such as Y combinator cannot be written directly by Haskell. Of course, you can use something similar to Y combinator (such as fix or laziness) in Haskell, but these do not reveal the essence of recursion, you just rely on the recursion implemented by Haskell to implement recursion, but you cannot actually understand how recursion is produced. With Scheme, you can easily write Y combinator and put it into use.
  2. Monad is not required for Scheme. Haskell is a pure functional (purely functional) language, all side-effects, such as printing characters to the screen, we all need to use a sophisticated concept called monad implementation. This concept is actually not essential. all its functions can be implemented through state passing. By writing State transfer programs, you can clearly see the nature of monad. Monad is a "design pattern" of Haskell ". Knowing this too early does not help you understand the nature of functional programming.

So why do we need to learn Haskell? That's because Haskell contains something that Scheme lacks, and there are no design issues with Scheme. For example:

  1. Pattern matching: Does Scheme have a standard, natural pattern match )? System, while Haskell's pattern matching is a beautiful implementation. Some Scheme extensions (such as Racket) have a good pattern matching mechanism.
  2. Type: Scheme treats all values that are not # f (false) as true, which is incorrect. In Haskell, Boolean has only two values: True and False. Scheme programmers claim that this can write concise code, because (or x y z) can return a specificValueNot just a Boolean variable. But in a few cases, is it worth the price of writing a shorter code? I see that this design has brought many unnecessary problems.
  3. Macro systemMacro (macro) is generally considered an important advantage of the Lisp series. But I should point out that they are not necessary, at least for beginners. In fact, if the semantics of a language is well designed, you will hardly need macros. The essence of macros is to allow programmers to modify their own language design and add new structures. However, the main drawback of macro is that it abused the extremely dangerous "power" of language change. In fact, only a few people have the wisdom and experience needed to change a language. If you allow common programmers to use macros, the program will become very difficult to understand. In fact, generally programmers do not need to learn how to use macros, nor to be guilty of skipping this item. When you develop to design your own programming language, you will naturally understand what macros are.

(Note: these are my own opinions and do not represent those of Scheme designers .)

Recommended books

The Little Schemer: I think Dan Friedman's?The Little Schemer?(TLS) is currently the best and most essential introductory programming material. Its predecessor is The Little Lisper. Many senior programming language experts have learned Lisp from this book. Although it is called "The Little Schemer", it does not use all Scheme functions, but ignores The Scheme mentioned above and directly enters The most critical topic: recursion and its basic principles. This book is not only thin and brilliant, but also very cheap (sold for $23 in the United States) compared to other programming books ).

SICP:The Little Schemer? It is actually a difficult book, so I suggest using it as the next well-versed book.Structure and Interpretation of Computer Programs? It is suitable for serving as the first teaching material. However, you only need to read the first three chapters. Since from chapter 4, the author began to implement a Scheme interpreter, but the implementation of the author is not the best way. You can learn these things better from other places. I haven't thought about where to learn it (maybe I can write a tutorial myself ). However, you may be able to start watching TLS after reading the first chapter of ASP.

A Gentle Introduction to Haskell: For Haskell, what do I start?A Gentle Introduction to HaskellBecause it is short. At that time, I already had Scheme, so I didn't need to learn basic functional languages. What I learned from this document is only Haskell's concept of type and pattern matching.Real World Haskell? It is a popular teaching material, but it tries to be all-encompassing, so many places are too lengthy. The most fundamental functional programming concept is TLS.

Over to object-oriented language

How can we transition from a function-based language entry to an object-oriented language? After all, most companies use object-oriented languages. If you have actually learned functional language, you will find it easy to use object-oriented language. Functional languages are much simpler and more powerful than object-oriented languages, and almost all functional language textbooks (such as SICP) will teach you how to implement an object-oriented system. You will have a profound view of the nature of object-oriented and its problems, so you will easily find out how to write object-oriented programs, and you will find some tips to avoid their limitations. You will find that even if you must use object-oriented language in your actual work, you can avoid the object-oriented way of thinking, because the object-oriented thinking brings about most of the confusion and redundancy.

In-depth nature and bottom layer

Is there no need to learn the underlying layer? Of course not. However, learning the underlying hardware at the beginning will be blinded by complicated hardware design and cannot clearly understand the simple principle.

After learning high-level languages, you can learn semantics and compilation principles. In short, semantics (semantics) is the study of how program symbols represent the "meaning" of machines. generally, semantics learning includes lambda calculus and the implementation of various interpreters. The compilation principle is to study how to translate advanced languages into low-level machine commands. Compilation principles include computer composition principles, such as binary construction and arithmetic, processor structure, and memory addressing. However, learning these things with semantics and compilation principles will get twice the result with half the effort. Because you can intuitively see why the current computer system is designed like this: why is there a register in the processor, why is stack required, and why is heap required ), what is their nature. These are even problems that many hardware designers do not understand, so their hardware often contains unnecessary things. Because they do not understand semantics, they often do not understand what components and commands their hardware needs. But interpreting them from high-level semantics will reveal their nature, so that you can understand how to design more elegant and efficient hardware.

That's why some programming language experts later began designing hardware. For example, Lennart Augustsson, one of the founders of Haskell, was later designed?

BlueSpec, an advanced hardware description language, can 100% of the synthesis (synthesis) for the hardware circuit. Scheme is also widely used in hardware design, such as Motorola, Cisco, and Transmeta. their chip design contains many Scheme programs.

This is basically my initial advice on learning programming languages.

Address: http://www.nowamagic.net/librarys/veda/detail/2107,welcome.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.