Digging just down

Original author: Evan Miller
  • Transfer
Hello dear readers.

Recently, we are interested in the Zed Shaw series " The Hard Way ", which I would like to at least partially translate into Russian. Since sometimes we really do not look for easy ways, I would like to start with a book about the C language: The series is aimed primarily at beginners. For those who love the C language, as well as for their opponents who believe that it is better to start with something simpler, we publish a slightly abridged article by Evan Miller, written at the end of last year. Perhaps, depending on the reaction to this article, we will decide to additionally translate and publish an excerpt from Mr. Shaw’s book or even his response to criticism made by Tim Hentenaar

In the meantime, we invite you to a cat, where, as it seems to us, the most general considerations in favor of the relevance of this book are set out.

When I learned to drive a car (I was then a little over 15), my mother insisted that I practice on my father's Mazda Miata: it was a silver two-door convertible with a convertible top.

Managing the Miata was not easy. Not only was there no automatic transmission in it, it was also almost impossible to look back from this machine. The sun had so fried the plastic rear window that it seemed that sandwiches could be made on a folded hinged top.

The Miata was by no means the safest car, and the Mazda Motor Corporation did not even try to state the opposite. It was just an affordable car, which is nice to ride, such a budget BMW. I remember my father’s Miata was so narrow and squat that when I rode it along the federal highway, thoughts even crept in: “And if I try to slip on it under the semi-trailer, the trucker will notice something”?

We also had a minivan and an SUV - larger and more reliable cars with transparent rear windows. Many parents would prefer to teach a teenager how to drive them. But not my mom.

“One day you will be at a party,” she explained to me with the confidence that Nostradamus would envy, “and there will be a car that no one can drive, because it will have manual gear changes. And you must be able to, and you need to learn this now, otherwise you will never cope with the shift knob. ”

Mastering a manual gearbox is not the most interesting occupation, and I think that I would never have done it if it were not for the prophetic authority that our mother used at home. But, having practiced, in the end I was able to ride the Miate within the permitted speed, without flooding the driver's seat with sweat and tears.

Many years have passed since then, and I noticed an interesting pattern. We, a proud minority - seasoned manual transmission masters - turned out to be much more skilled than those who used to rely on automatic transmission. We more confidently owned the car, better imagined how the car engine works. Even if we never had a chance to look inside the gearbox, we knew what “ overdrive ” is in an automatic gearbox , how to save gas with it. We knew what the mysterious numbers 1 and 2 under the inscription “Drive” mean, what service they can do when you go down the slope. And at every moment of time, we, probably, on an intuitive level had a better idea of ​​what was happening with the machine - better than the adherents of the automatic transmission.

I do not regret that I once mastered the manual transmission, although I did not manage to bring significant benefits to society - for example, I never drove an ambulance in a quick fire in which orphans would sit. Just manual gear shifting is a good skill, it will not hurt anyone. I think the more drivers they own, the better.

Dear reader, I did not write all this in order to advertise myself as an excellent driver of low-budget convertibles, and not to oppose the dominance of automatic transmissions in the automotive industry. In fact, I just see important parallels between the distribution of such boxes in the automotive industry and the Python language in programming.

Python is convenient, in many respects it significantly exceeds the C language. But if you teach a teenager to drive an automatic transmission, you can be almost sure that he will not even think about mastering gear shifting. Advising neophytes to learn Python, we produce neophytes who will never try to write code in C. I think this is bad.

Expressing this opinion, I find myself in the minority, therefore I want to clarify my point here. Not so long ago, Python replaced Java as the most popular introductory programming language studied at universities. Eric Raymond, author of the How To Be a Hacker program article, recommends Python as the first language. He is certainly supported by Peter Norvig in his famous work “Teach Yourself Programming in Ten Years”. Paul Graham even talks about the specific "Python Paradox."

Nowadays, if you see ads in the spirit of "How to Learn to Program in X Weeks" - you can be almost sure that you will be offered to learn Python.

Contrary to the surface appeal of Python - its syntax, interactivity, library support, wide community, and excellent documentation - choosing it as the first programming language, you are faced with a serious problem. A programmer who knows only Python does not have enough understanding of how a computer works. He may perceive C as a mystical art, evoking mixed feelings of fear and hostility. Fear - because the programmer was told that C is complex, and hostility - because the complexities of C are supposedly obsolete remnants of more ascetic times. There was even a new truism: "human time is more valuable than processor time."

But Python and C are not just alternatives to each other, where one language is a slower and more convenient replacement for another. Python also cannot be considered an absolute technological advance over C. It is better to perceive Python and C as languages ​​that coexist in independent parallel slices of reality, where C is one level closer to the machine.

Paul Graham picked up a beautiful metaphor (as always, right?) About the potential of programming languages, which he describes as a kind of vertical continuum. Languages ​​with minimal features are located at the bottom, with maximum languages ​​at the top. Somewhere in the middle is the hypothetical Blub language, which is slightly less than completely reminiscent of C. Graham believes that Blub users will despise all the languages ​​below Blub in this continuum - Cobol, machine language, etc. - and they simply won’t be able to understand the capabilities of those languages ​​that are higher.

This is a great image, but let's look at this metaphor on the other hand. Python may be higher than C, and Lisp is like a cherry on an abstraction cake, but learning Python or Lisp doesn't help much to understand how the computer that runs this continuum is based on. Thus, in spite of the fact that Lisp programmers seem to be omniscient celestials, in the hierarchy of programming languages ​​looking “down” is no easier than “up” .

In fact, I would even say that looking down is harder than looking up. A clean Lisp boxer looking at C code only sees bad syntax, unfamiliar functions, and mysterious comments about cache lines. And the C-programmer, looking up, sees a whole bunch of things implemented in C.

The popularity of Python is due to the fact that it occupies a position above the average in the described continuum. It is more abstract than C and more productive in work, but not so abstract that your head goes round from metaprogramming and recursion.

The trouble is that just as Lisp seems pretentious and redundant to the average Blub programmer, so C makes a similar impression on the nutritionist. What are these signs everyone is talking about? “It sounds sophisticated (the pioneer thinks), and if I still work somehow without these pointers, I can do without them further.”

Therefore, most drinkers will never learn C.

Undoubtedly, you can make a long and successful career in IT without knowing C. However, a programming culture without learning C gives a number of perverse effects that are directly related to the fact that a person becomes familiar with programming using the Python example.

Firstly, fewer and fewer people are able to write excellent programs. To program perfectly - for PCs, mobile devices, alien spaceships - you must have a clear idea of ​​how the computer and operating system function at the lowest level. How many data structures fit in the processor cache? Why is the code slow and the built-in profiler claims to be fast? When I order the operating system to do something, what does it really do? I think all these things can be memorized, but nothing helps to acquire the necessary intuition as much as writing and optimizing a large amount of C code.

You may argue that at this historical moment it is more important to write more programs than more quality programs. Perhaps from an economic point of view it is. Technologies are developing very quickly, there is no need to write a filigree-worked program that no one needs. But the culture of “just use Python”, “computers are fast enough now” and “let the hardware solve the problem” lead to a deep systemic crisis: when they enter the profession through Python and tackle C, fewer and fewer wiseacres will fall into professional programming.

Temper anger for a moment and listen to my arguments.

I believe that for such "smarties" who are going to study programming, Python as the first language is unattractive for two reasons. First, learning Python is not that difficult. The key concepts of this language do not properly cling to tech-intellectuals and, accordingly, do not cause much interest. Learning Python, I would say, is somewhat boring. It’s like going to school where there are no specialized classes.

The second mechanism was described by a friend of mine who recently signed up for a Python workshop. She said that she enjoyed learning cycles and functions with great pleasure. They were small, understandable, self-sufficient. But then the teacher decided to demonstrate “all the power of Python” and spent the rest of the lesson writing some useless Python Twitter API program.

Using libraries is an important skill; any professional developer will confirm this for you. However, if you prematurely get acquainted with libraries, then they erect a whole wall of abstractions, at the sight of which smart people feel simply bewildered. So my friend thought she was about to study the secret laws governing computers; instead, the teacher simply rolled out a monolithic user application in front of her with a completely impenetrable abstraction of the client library. Not having mastered, first of all, the language - and not having learned to read the source code of this library - my friend was without tools with which I could dig deeper and understand what was happening at the bottom of the chain of calls.

“I just got a bad workshop,” you say. But with this example, I want to emphasize a larger problem: not having studied C for starters, the programmer is deprived of the necessary tools to understand what exactly is happening in the system used . If you are a smart and inquisitive nutcracker, you will soon get to the bottom of the tight tongue of C. Under these horizons, they will tell you, “fear dragons, bones, and debuggers.” Accordingly, if you are not brave enough and do not ignore the warnings “do not take this C,” you will never explore the depths that you can climb just out of curiosity.

On the contrary, a syshnik trying to understand a piece of C code, in the worst case, would have to shovel a bunch of header files, man-help and source code. But he hardly comes across any strange Lisp or Python package. They always dig down, not up . This is the essence of computers.

The programmer’s motivation can be twofold: either solve the problem as best as possible, or understand how certain things work. Undoubtedly, Python is great for solving problems. This is evidenced by the popularity of Python at startups and university courses (including Data Science). If you are going to learn only one programming language in your life, then Python is a reliable, efficient and reasonable choice.

But Python is completely unsuitable for those who are interested in the principles of computer operation. This is a problem because in the long run, the very best programmers come from people who are overwhelmed by a craving for knowledge. Perhaps in the short term they are not the best employees - they read books at work, introduce some kind of senseless optimization - but, having passed a sufficient number of rabbit holes, they will be able to draw you a real map of wonderland.

This, I believe, is the real problem with “programming without C” - as well as with the more global idea that introductory programming languages ​​should be “expressive” and “accessible for beginners”. The programmers guild is losing just those people who could decorate it with themselves.

I want to emphasize that I do not mean people who want to combine programming with their main work (scientists, journalists, web designers, etc.). I am talking about those who are interested in programming as such and think that one day they could succeed in this matter.

I will also briefly dwell on why Python is taught at universities (we used to teach Java). The main reason is that the task of universities is not to educate aces programmers. Most faculties simply try to prepare as many successful graduates as possible who will go to graduate school or find a well-paid job. Neither one nor the other requires exceptional programming skills.

From the point of view of the teacher, a programming language is a material on which to study the basics of computer science: algorithms, data structures, etc. Python is the middle ground because it is easy to learn (professors are happy), and it is also used in commercial projects (professors are jubilant). Combine Python’s popularity with universities, its abundance of online materials, and the widely cited (and rarely disputed) claim that Python is a “good learning language.” Well, what could go wrong with him?

It seems to me that people who get into programming through Python are missing a ton of interesting things. There is a widespread belief that the buzz of programming is to solve a variety of tasks in a minimal amount of code, using the client libraries with might and main. This is true in cases where a person must cope with work, meeting deadlines. But if your main motivation is to learn something and become a first-class programmer, then it will be much more interesting to write programs that do not work as efficiently, but leave room for thought.

For people who have never programmed before, C is a great simulator. Pointers and their arithmetic have no close analogues in the everyday world. By learning this language, you will come across seemingly meaningless error messages and deal with non-deterministic failures. If you have problems with arithmetic, then you can damage the call stack; forget about a simple check of the boundary conditions - and the heap will sprinkle like a house of cards. Sometimes you want to break into the monitor or sob on the keyboard.

But it's worth it: C helps you get a good idea of ​​what the computer does. You will feel like a teenager fighting a manual gearbox. By asking “why?” And digging deeper, you will gradually learn the process model, processor architecture, memory hierarchy, understand the operating system, etc. It is this mental model, and not the C language as such, that will help you navigate the abstractions that others have written and create programs that once seemed unthinkable to you.

So, if you want to learn how to masterfully program - in any language - then do not give in to persuasion to learn Python or, God forbid, Lisp, but start the path with C. There are gorgeous views from above, but if you want to conquer a mountain, it’s better to climb it just below.

Only registered users can participate in the survey. Please come in.

About Zed Shaw Books

Also popular now: