📜 ⬆️ ⬇️

John Carmack on the science and art of software development

From translator

I apologize for the slightly free translation. I tried to keep the idea as close as possible to the original, but at the same time make the text a little more coherent. In the original, this is a transcription, and quite complicated.

I also apologize for the lack of translation of the phrase “computer science”. In the Russian language there is no adequate phrase. Any “computer science" and "computer science" are either discredited concepts or meaningless translation substitutes. The English concept of “computer science” contains a historical play on words, which, when translated into Russian, should look something like this: “the science of computing, information processing and computing devices”. I think it's better to leave the original “computer science”. In any case, in this form, this phrase will allow you to choose the necessary context from the variety that it represents in the original.

Why did I decide to translate this text (because it is short and not very saturated with revelations)? Because this is Carmack's performance. And he, after all, is a symbolic figure in the software development industry. What is written below shows the separation of software development theory from practice. After all, if these thoughts are visited by such a developer and put to QuakeCon, then what is happening in the heads of ordinary application programmers?

From the author of transcription, Andrew Co.

I am not particularly fond of computer games, but, nevertheless, I owe them my hobby for programming (it started with rendering algorithms). So when I saw John Carmack speaking at QuakeCon 2012 in my tape, I thought that I should listen to him. Suddenly I find out something new about creating computer games?
')
In fact, instead, I heard a story about how “the most programmer of all programmers” recently realized that software development is an applied aspect of sociology. For ten minutes, he talked about the human factor in relation to developer errors, the development of programming languages, static analysis, code checks, developer training, and cost / benefit analysis.

Below is my transcription of this performance. I apologize in advance for errors.

Speech by John Carmack


In an effort to make games faster (and this, in fact, what makes us move forward), we made a lot of mistakes in the Doom 4 code. Let be. These errors, one way or another, will remain in the past. But the very desire to make games fast is necessary. Because you can not release a new game every six years.

If we talk about software development ... You know, I gave one interview at E3, in which I mentioned that I am constantly learning, and in each new year I’m growing above myself last year’s from a professional point of view. The interviewer was still wondering how I manage to grow over myself for 20 years? But, in fact, in fact, I was growing above myself rather weakly - both from the point of view of my own mastery, and from the point of view of understanding the dynamics of the team development process of software. Perhaps, I deliberately didn’t pay attention to this moment for years, because, you know, there is a temptation to present myself as a sort of scientist and engineer who categorically declare that there is an abstract concept, there is a provable, and there an objective one. This is “computer science”. The science.

Now, I will explain what this moment is.

In reality, it's not like that. In “computer science”, you are a scientist when you speak of algorithms as “things in yourself”. When you optimize algorithms, you become an engineer. But the algorithms (the scientific part) and the optimization (the engineering part) are trivial as compared to the programming process itself.

We have very few programmers who deal exclusively with optimization and algorithms. 90% of our programmers do the usual routine. Meat, forcing the skeleton to walk.

When I began to figure out how and what they were doing, I realized that there was no science, no engineering, no even an objective approach to the problems they were solving. You know, one of these programmers even said that he works as a monkey — he writes stupid code that solves some small applied problems.

You (and me, to be honest) like to think that we are smart engineers, that there really are academic ways to write good software. But the more I look at all this, the more I understand that it is not in academic ways.

We can measure and reproduce something using scientific tools for measuring, reproducing, evaluating and testing. After that, we can select certain algorithms and even optimize them in some way. But everything else that we do next has nothing to do with science or engineering. All the rest is a matter of social interactions between programmers. Or even a programmer with himself at different times.

Here you can, for example, start talking about functional programming, lambda-numeration, monads - it's all nice and very naukhoobrazno. But all this does not affect what specifically and how specifically you are developing. Yes, these "techniques" and useful things allow you to eliminate certain classes of errors made by abstract developers. But, you know, all that I can do with the use of a pure functional language (and this, as you know, is the most academic, scientific and strictly formalized way of solving problems) - all this will be transformed into exactly the same assembly code that will be converted a similar solution implemented on some BASIC or something else of your choice.

Regarding this, I would like to give an example with my eldest son - he is learning programming right now. I, in fact, had thoughts - would I teach him something like Haskell in seven years? It’s good that I had enough common sense not to give these thoughts a further course. And not because I know Haskell is so bad that I could not teach another person who learns programming from scratch. Not.

I thought about it and found out that all this is just artificial layering on top of truly fundamental knowledge, which in the programmer community is unjustly implied due and taken for granted.

Even if you go back from functional programming to structured - all this meaningful wool from a programming course from while and for loops to explaining how a computer works is nothing more than a semantic superstructure, for example, over flowcharts.

"If it is, then, otherwise it is, and not this." Explanation of the reason for use in a particular location for a particular purpose of a while loop or for loop. These are conventions that help people avoid common mistakes when developing any software. At the same time, all such agreements and clarifications have nothing to do with what actually happens inside the computer. They are intended only to stop people from making common mistakes. Those mistakes that are made by all, constantly and persistently.

It has been a long time for me that programmers must make mistakes with some frequency . Last year I talked a lot about the fact that we became acquainted with static analysis and drove all our code through it, as a result of which we received hundreds and thousands of identified problems. And this is very cool - now you can raise the story, say “Look, here I made a mistake” and show everyone the place where the mistake was made. Everybody will see and note for themselves: “Oh, how can it be! Hmm, I'll try not to let that happen. ” This is good, but the problem is not the result, but the reason. If the syntax allows you to implement something incorrectly, then this “something” will be incorrectly implemented. That is why, besides the input of static analysis, I would like to limit the expressiveness of language means more and thereby protect programmers from making mistakes .

More recently, I began to conduct daily code inspections, in which I run through changes and look for something indicative of discussions with the team. I look at a small piece of code and talk about where the error is in it. In fact, showing errors from live code is not such a big social evil. Although the live code makes the authors feel uncomfortable, it shows the nature of the error with its clarity and prevents it from spreading further on command. This is much more efficient than individual code inspections. I think the team has already mastered and does not feel discomfort from the removal of errors for all to see.

In addition, in some unobvious cases (for example, if the const specifier has a function parameter), it is possible to objectively clarify their point of view (“this redirection is a list for caching”, “such a lack of a specifier will cost us such computational resources” “We can measure these resources”) - and at the same time make such an explanation as reasoned as possible. After all, it often happens that you, due to experience and many years of work with a particular subject area, faced a problem and talk about it. And people, in response to your words, say, “No, I haven’t seen anything like that. No, this is not a problem for me. I do not make such mistakes . ”

The more I realized that there was no science that could cope with the banal human vices, the more I wanted to find some way to overcome these evils. After all, it seems, we all want to become the best developers, produce the best products and better do everything that we do - but at the same time, we educate dozens of interchangeable workers who would do the work in the same way. After all, we know that we have a routine. We know that people come and go. We know that people new to the project look at the code and do not understand its purpose and writing style conventions. And we know that there are certainly ways to do it all as better as well as worse - but these methods are extremely difficult to formalize.

I spend more and more time searching for these methods. For example, looking through the reports of the NASA software development lab, I did not understand the value and purpose of most of the developed products. All more or less valuable products were fully automated, carried out analysis or calculations without human intervention, or made some decisions. At first, I thought that as our projects grew, they were getting closer and closer to the NASA products in terms of code base size, and we should use the same methodologies that NASA uses. But, unfortunately, if you look at the reports of NASA and the volume of the code base of their projects, then there are “big” projects with three or four hundred thousand lines of code. In our game engines, the code is much larger. In general, it is fun to understand that the game engines (what animates computer games) are built inside more complicated than the software that controlled the flight of people to the moon and back, controlled the shuttle, forced SkyLab to work or worked on the orbital station.

The truth is somewhere nearby, but certainly not in the NASA methodologies. If you use their approaches, you can get a very correct code, but at the cost of very low productivity. Unfortunately, our work is driven by a cost-benefit analysis, and in this case it says that “you can be perfectionists, but the output will not be the software you need, but the deadlines will be disrupted”. On the other hand, if you work quickly (maybe not very carefully), you can get quite cool products. And in a short time. But then there is the problem of using the right tools and properly built work with them, because, without solving this problem, you can quickly get "cool" software - and then live with it for years and constantly suffer. I think that we, unfortunately, still have where to grow in choosing a compromise between these two options for building a workflow.

We know why and how our code lives. Seriously, we look forward to the decade. I tell the guys that the code they have written now (if it is, of course, not focused on any particular game) can and most likely will live for ten years. And this code will be used by hundreds of programmers. They will read it, address it in some way, and this is a serious responsibility. I firmly believe that we are obliged to impose very stringent requirements on the analysis and separation of what remains in the past from what we will continue to live with. Unfortunately, besides this there is a huge amount of nuances in the development of multi-level API, there are a huge number of other unobvious things - and they all require a masterful, creative approach. I want more tools to work with such delicate matters. And I spend a lot of time getting these tools with us.

Source: https://habr.com/ru/post/150260/


All Articles