Probably, this article was worth publishing before the previous two, in this my cycle about Common Lisp, but better late than never.
Once upon a time, when I read Paul Graham's articles, and was just beginning to learn CL, I was quite skeptical about the statement that Lisp allows you to understand other languages ​​better, and indeed, a programmer who knows CL will learn any other language for a maximum of a couple of weeks, and will write on it even better than most people who know this language for a couple of years write on it.
But now I came to the conclusion that this statement is still true.
Believe it.
New ideas in programming languages ​​have not appeared since the mid-90s, that is, just since the standardization of Common Lisp.
')
If you pick up one of the current implementations of CL, such as SBCL, more or less understand the standard ANSI CL and its extensions provided by the implementation, then you will comprehend and understand programming paradigms like:
- Imperative and its variations (in the CL there is even a goto! And the rest of the control flow controls in it are rolled out by analogs from all other languages)
- Structural (no comment)
- Object-oriented and its variations (From closures to CLOS)
- Functional (CL encourages localization of side effects and writing whenever possible without them)
- Event-oriented (which is reduced to callbacks, that is, function objects)
- Generalized (see the end of the article about polymorphism)
- Metaprogramming (after all, this is Lisp! The program itself is an object of the language)
- To a certain extent, parallel programming
- And so on and so forth - using language tools that directly implement the previous paradigms, and sticking all macros, the CLOS and the condition system , you can add anything to the language, starting with the logical paradigm and the built-in prologue, and ending with visual programming.
I explicitly say that all mainstream languages, and especially object-oriented, are subsets of CL, just with their syntax and some limitations in the field of typing (
the CL type system is very simple, but at the same time, infinitely powerful and unsolvable in full even in dynamics).
In principle, this is true even for C, since I was convinced from my own experience that working with FFI and the built-in assembler helps to understand C and ordinary assemblers more than even working with them.
Many functional languages, including esoteric, languages, after becoming acquainted with CL, will not look that esoteric, and will be, in principle, in full view.
To a certain extent, modern CL implementations will help to deal with common for all languages ​​techniques of code optimization, with many low-level concepts (see above about C), with multithreaded programming, and generally with parallelism (do everyone know where Google got the idea of
Map Reduce ?) , and even with the principles of building complex systems (although this, of course, comes more with experience).
I’m only talking about languages ​​and general programming concepts, not talking about specific frameworks and libraries, and any things that are orthogonal to the actual language concepts, but you may also be more productive in learning them, noticing patterns that you know about polis and therefore structuring information faster. For me personally, some time ago, some experience with CL helped me to better understand the essence and purpose of XML, but somehow I helped to understand the organization and general principles of building graphical interfaces and GUI frameworks.
There is also Haskel, yes, which, they say, also “enlightens”. But personally, I think Haskel is some syntactic sugar over a couple of basic concepts that are actually available in Lisp, only in a more general, and, from this, less noticeable, and of course, less mandatory, form. These concepts are:
- Pattern matching (well, ADT , yes, but ADT is essentially only needed for pattern matching), which is a kind of dynamic multiple dispatch.
- Laziness, which comes down to streams and closures.
- Polymorphism (which, in fact, is the reason for the presence of all this husks with types in Haskel). Parametric polymorphism is, conceptually, a subset of dynamic typing, and ad-hoc is a dispatch by type (which in lisp can be achieved with both simple if + typep and more powerful mechanisms like CLOS). Someone will say - but after all he is in compile-time in Haskele! Yes, but I do not think this is something so special - if you lock it up, you can write macros and transfer operations on types in compile-time and in Lisp (and no, for this you will not need to invent a new language "above" CL, you just need to work with objects of “lexical environments”, which, although their specific format is not specified in the standard, are present in all major implementations and provide information about types), though you will have to work only with a subset of the CL type system, since in general it is insoluble even in dynamics, as I have already gone Orillia.