When I was still a freshman, I met another student who claimed that he could write code in any programming language that I could call. I was somewhat shocked and replied with a podnachka:
- What, even in that unreadable esoteric language, where there are only a couple of teams that barely pretend to be a Turing machine?
- Yes, this language is called brainfuck. I know brainfuck.
And it was not a trick - we checked. I called a programming language known to me, he spent a couple of minutes on the Internet to refresh his knowledge of it - and was able to write working algorithms in this language. I could not understand it. He, like me, was then about 18 years old - how could he know all these languages at that age?
')
Brainfuck interpreter written in brainfuckToday, I still respect that demonstration of the skills of my classmate, but I am no longer shocked by it. After I learned more than one programming language, it became clear to me that they differ significantly from each other than would be expected. At some stage of training, I already paid attention not so much to the syntax of a programming language, but rather to the ideas underlying it, the memory model, the principles for executing instructions. All this can be called the theory of programming languages, from the point of view of which different languages simply implement several different versions of the same basic ideas.
Today, I advise my students to "try to learn all programming languages." Think for yourself - because this idea is better than all of these “This year I will learn Go! Oh, no, now they say that in the fashion of Rust - I will learn better Rust! Or Swift ... ". Just learn everything - you can't go wrong. And this article may help you in this a little.
And immediately - a disclaimer :)
- I never say that you need to really learn 500+ (or how many actual ones are there now?) Of programming languages. I'm talking about the need to understand the basic paradigms and implementation of patterns, which will give you the opportunity to understand almost any constructs in almost any language. A forgotten keyword or function from the standard library can always be found in the documentation.
- This is not a five minute deal. Perhaps you will go far on this path in some year. But, you know, a decade may well go
- We'll have to explore some of the already outdated or not yet fashionable concepts.
- Depending on your main job (or life goals), all this may never be useful to you.
Then why do this?
If you see some significant part of your career related to writing software, then you should be familiar with programming languages:
- Even without choosing any specific programming languages (or choosing just one) after a couple of years of work as a programmer, you will find that you have already written (or read) code in several languages. So for some reason it always happens
- You will find that having knowledge of several programming languages, you will want every time to be able to choose one of them to solve various problems.
- Programming languages are flourishing and becoming obsolete. Knowledge of several of them gives you the opportunity to stay on the cutting edge of progress, have access to more interesting projects or good companies.
- Many important projects require a fundamental understanding of the work of compilers and knowledge of several programming languages. These are implementations of development tools, standard libraries, domain-specific languages, IDE, browsers, databases, static analysis tools, etc.
Personally, the last item seems to me very important. Ras Bodik well
emphasized this point in his lecture to Berkeley students when he explained the importance of studying the compiler development course:
Do not be the developers of template consumer software. Instead, try developing new tools for users and other programmers. If you draw a historical analogy, who would you rather be like: an employee at a loom who performs daily operations or develops new models of such machines?
Step number 0: stop calling yourself a “Rails programmer (substitute your language / platform)”
This is a simple but important step. Yes, you probably already have some kind of specialization and you may be proud of it and continue to improve it - this is good. But at the same time, such self-identification creates a mental barrier in your head. Each new technology, each new language is perceived with a hint of skepticism or criticism, and possibly neglect - and this is already bad. Start calling yourself simply “software engineer” or “programmer”.
An example would be Alex Gaynor - a great Python specialist, one of the Core Developers of such things as Django and PyPy, a member of the board of directors of the Python Software Foundation. But once he was asked for help by
United States Digital Service - and Alex
spent several years in projects on an ASP (not even on ASP.NET, but on that old ASP). Do you know why? Because he is a software engineer, not a Python developer.
Step number 1: go to the meta level
There is such an old anecdote about how an applied physicist accidentally came to a conference of theoretical physicists. He turned to one of the speakers and asked how he even managed to think about all these things, occurring in 11 dimensions? The theoretical physicist replied, “Oh, this is simple. Just imagine N measurements, and then fix N equal to 11 ".
A good programmer can use the same trick. You can listen to all these stories of marketers that “Go is a new and ambitious programming language”, or you can simply define it for yourself as a compiled statically typed language with garbage collection and CSP competitiveness style. Swift can be a “new and carefully designed” well or simply compiled general-purpose multi-paradigm language implemented on the basis of LLVM.
For those who have never had the opportunity to study compilers, I can advise a few excellent books and online materials. Firstly, this is a course from Alex Aiken, which was once available on the Coursera, and now on Stanford’s own platform (
Lagunita ). Not bad and the course from Berkeley - CS164. True, they stopped publishing its updates in open access, but 2012 materials seem to be still available.
The canonical handbook about compilers:
“Compilers: Principles, Techniques & Tools” . She is the Book of the Dragon. Like all books of this level, it has both fierce fans and irreconcilable critics. Personally, I consider it an excellent material, but be prepared for the fact that some of its parts will have to be re-read more than once before full understanding. There is a more simple and practical book aimed at
Language Implementation Patterns . If your interest is limited to a specific practical task of a small scale (like writing a domain-specific language), then this book will work better than the classic Book of the Dragon.
Dragon bookStep number 2: start with primary sources
With a good theoretical basis, it will be easier to learn new languages, but it’s still not so easy to take and learn all the 500+ more or less relevant programming languages today. Therefore, one can begin with the definition of languages in which some fundamentally new ideas were first investigated and implemented. On their basis, the study of similar tools in newer languages will be a trivial task.
Peter Norvig gives some
tips on which paradigms are really important, and also in which languages they were first implemented:
Learn at least 5 programming languages. Your knowledge should include at least one language with the classic abstraction of “classes” (it can be Java or C ++), one functional language (like Lisp, ML or Haskell), one language with support for syntactic abstraction (like Lisp), one declarative language (Prolog or C ++ templates), one language with advanced parallelism support (Clojure or Go).
I think this advice is an excellent base, but you can go this way further. First, I advise you to learn language C as early as possible. It is so omnipresent and important that it simply cannot be ignored. In addition, the study of C makes it much easier to study other languages, since well, very many of them took some ideas or parts of the syntax from C.
I also recommend learning any assembler. This can be MIPS (if you want to spend less time on training) or x86 (if you want to have practical use). This will give you more knowledge about computer architecture and processor device than about programming languages, but if in the future you want to write a compiler, then this knowledge is what you need. Perhaps someday, instead of an assembler, it will be possible to recommend studying the format of the intermediate code LLVM.
Peter Norvig recommends learning declarative languages, but I would be more specific here and would advise you to learn a logic programming language. It can be either a classic Prolog or
miniKanren .
In the section "languages with concurrency support" to the options mentioned, I would add CUDA. This is a qualitatively different scale of parallelism, because hundreds of GPU cores can not be compared with some 4 cores of conventional processors. You will not only understand the GPU device better, but also lay a good foundation for yourself to further explore machine learning (there, parallelism and computing on the GPU will be very useful). But it is important to understand that you need both CUDA knowledge and one of the mentioned languages with parallelism for the CPU (like Go, Clojure or Erlang).
Vector programming is another powerful paradigm. Norvig in vain missed languages with his support, because they have quite specific application in use. Classic examples can be APL / J / K / Q, as well as Matlab.
There is also such a thing as highly specialized languages. Sometimes creating your own highly specialized language for specific tasks can be the right decision. But in order to decide on this, it is necessary to study specific examples of when this approach was successful. I advise for this to look at things like Frink.
Perhaps I have already suffered a little, but it is so difficult to stop when there is so much all that is delicious! Someone will say that you should not miss learning Forth in order to understand stack languages (although it seems to me that the work of stacks can be understood in other languages). Someone will say that I have missed a very important language X or a whole category of languages Y - and this will be true, because there are a
lot of them.
Step number 3: practice
Simply make a list of languages that you plan to learn. But to really take and study - it will take some time. If you are lucky, you can apply some of them in your main job. But even if this does not happen, you should try to find a way to learn a new language not only from a theoretical but also from a practical point of view. Without theory, progress will be slow, but without practice you will be stuck.
A good way to start learning a new language is to read a short squeeze on
Hyperpolyglot or
Learn X in Y Minutes . This will give an approximate understanding of the key ideas of the language and remove the fear of unfamiliar syntax. If you are already familiar with some similar language, then Hyperpolyglot has a very convenient language comparison function - this can surprisingly quickly move you into learning a new language.
Another useful exercise would be to study not even the syntax of the language, but the document, which describes the motivation of its creators. This will give you an understanding of why people in general spent their time and energy on creating this thing, what their motivation was and whether it can now or in the future coincide with yours. For example, if you are afraid to study C ++ deeply or are skeptical about some of Stroustrup solutions, you should definitely read
The Design and Evolution of C ++ . Most other programming languages also have somewhat similar publications.

After that, you can already read a book on the language or go straight to trying to write something not very difficult on it. As for books, it is difficult to give some general recommendations, but I would still advise you to choose the most well-established, proven over the years things written for experienced programmers who are learning a new language. Such books are often written by the authors of the language themselves and emphasize their main ideas, while more modern publications are aimed more at the practical application of languages in various spheres.
The fastest way to join a new language, in my opinion, is to find a set of small tasks and gradually solve them.
Exercism.io can be a good source. In addition to the tasks there are even tests that make it possible to quickly assess the quality of your implementation. The solution of small problems is in good agreement with the study of the theory and with the main work on other projects.
Once you are comfortable with the syntax and small tasks will no longer cause you problems, I advise you to find a big project in this language. And it should be a project in the area for which this language was created. For example, if you are learning C or Go, write a command line utility with a large number of system calls. If you are learning Python or Ruby - try to write something algorithmic and not very demanding on performance (AI for tic zeros :)) well, etc.
Keep digging
Given the number of programming languages in the world and the fact that we really use even very old languages like C, it is easy to conclude that humanity has already invented all the programming languages it needs. But this is a very controversial assumption. There is a very significant gap between what is considered possible to be programmed and what we have learned to program today. And the problem is not in computing resources - with all the existing hardware platforms and clouds today we have where to drive the code. The problem is in our ways of communicating with the computer, so that we can not always comfortably express what we want to get at the output of the program and how this should be calculated.
Gerald Jay Sussman drew attention to this in his amazing report,
We Really Don't Know How To Compute . It uses a somewhat outdated toolkit, but the tools that exist today do not give us any qualitatively different approaches to solving the problems highlighted by it.
Triangle of illusions. A person immediately sees in this figure a triangle, but you need to spend considerable effort to teach a computer program to do it.One of the people working at the forefront of science in the direction of developing programming languages is Chris Granger, working on
Eve . He wants to develop not only the language, but also all related tools. The language will be just one of the important components of a common platform. I don’t know if Eve will become a new generation of mainstream platforms, but I believe that this approach, extending and complementing the language with supporting tools, can become part of the future. At least, this will give the opportunity to better explain to the computer what we want from it. As Ras Bodik mentioned above (and I repeated), I would like you to be a part of this progress. Learn all programming languages, not just one language. Understanding the basics and principles allows you to see further and be ready for the emergence of a new one.