Paul Graham: Brevity = Strength

Today at HackerNews we raised a discussion of the article of Paul Graham in 2002 and we decided to resurrect its translation from nonexistence.

image


"The quantity of meaning compressed into a small space
by algebraic signs, is another circumstance that facilitates
the reasonings we are accustomed to carry on by their aid."
- Charles Babbage (1791-1871)


In a discussion around the LL1 Revenge article on the LL1 mailing list, Paul Prescod expressed an idea that doesn’t leave my mind.

Python's goal is regularity and readability, but not brevity.

At first glance, a programming language probably should not claim to be. As I understand it, brevity (succinctness, conciseness, compactness) = strength. And if so, then making a substitution, we get:

Python's goal is regularity and readability, but not power.

which, in turn, is not a very good compromise (if it is really a compromise), which is worth making. It seems like if you say: the goal of the Python language is not to be an effective programming language.

Is brevity = strength? This seems like an important question, maybe the most important question for those involved in the development of languages. I’m not sure yet that the answer to it is simply “yes”, but for a start this is a good hypothesis.

Hypothesis


My hypothesis is that brevity is power, or they are so close that, with the exception of pathological cases, you can take them for something identical.

Brevity, it seems to me, is what programming languages ​​are created for. Computers would be just as happy if they were given instructions directly in machine language. I think the main reason we are going to develop high-level languages ​​is to get the advantage of expressing (and more importantly, thinking) ten lines in a high-level language, which would require 1000 lines of machine code. In other words, the main goal of high-level languages ​​is to make the source code shorter.

If the shorter source code is the purpose of high-level languages, and the strength of something is a measure of how well the goal is achieved, then the strength of the programming language is how much it reduces your programs.

Conversely, a language that doesn't make your programs smaller does a poor job of a programming language, just like a knife that cuts poorly, or illegible printing.

Metrics


And in what sense is less? The most common measure of the size of the source code is the number of lines. But this measure is common only because of the simplicity of measurement, and I do not think that anyone believes that it is a good test of program size. Languages ​​have different conventions on what can be placed on one line; quite a few lines in C may have nothing but one or two separators.

Another simple test is the number of characters in the program, but this one is not too good; some languages ​​(like Perl) have shorter identifiers than others.

I think the best measure of the size of a program can be the number of elements, where the element is something that could become a separate vertex in the source tree. The name of a variable or function is an element; an integer or a real number is an element; a text literal segment is an element; an element of a pattern or format directive is an element. There are boundary cases (is "-5" one element or two?), But I think most of them are the same in all languages, so they will not affect the comparison too much.

This measure should be concretized, and it may require additional interpretation in the case of some specific languages, but it seems to me that it is trying to measure the right thing: the number of parts of the program. The source tree is what you draw in your mind to represent the program, and thus the size of this tree is proportional to the amount of work needed to write or read it.

Design


This measure would allow us to compare different languages, but this is not, at least for me, its basic value. And the value of the brevity test is a guide to designing languages. The most useful language comparison is comparing two possible variations of the same language. What can I do in the language to make programs shorter?

If the conceptual load of a program is proportional to its complexity, and a given programmer can withstand a certain conceptual load, then this is the same as asking: how can help programmers do more? And this, it seems to me, is the same as asking: how to design a good language?

(By the way, the falsity of this already bearded saying “all languages ​​are equivalent” is most clearly seen when designing languages. When you create a new language, you constantly compare two languages ​​- one in which I would make X, and the other in which I would not - so that decide what’s better. If it were a pointless question, you could just as well throw a coin.)

Having a goal of brevity seems like a good way to find new ideas. If you find a way to make programs shorter, then this is no coincidence: you probably found a useful new abstraction. You could even write a program that would fetch repeating chunks in the source code. New ideas can be found among languages ​​that have a reputation for being concise: Forth, Joy, Icon.

Comparison


The first one to write about these things was, as far as I know, Fred Brooks with his book Mythical Man-Month. He wrote that programmers generate the same amount of code regardless of language. When I first read it in my 20s, it was a big surprise, and it seemed to me that this had huge consequences. This meant that (a) the only way to write programs faster is to use a shorter language, and (b) the one who bothered to do this will ask a beat to those competitors who do not.

Brooks conjecture, if true, may be the very essence of hacking. Since then, over the years, I have paid attention to everything that would be relevant to the issue: from theoretical studies to stories about individual projects. I did not see anything that would contradict this hypothesis.

But I have not seen any clear evidence, and I do not expect to see them. Studies such as comparing the Lutz Prekelt programming languages, although they produce the expected results, they tend to use tasks that are too small for a meaningful test. The best test for a language is what happens in programs written in a month. And if you are convinced, like I, that the main purpose of languages ​​is to be a good language that they think in (rather than a language in which they give instructions to the computer after you think about it), then the real test for the language is what new can you write on it. Thus, comparing languages ​​based on a predefined specification is somewhat wrong.

The real test for the language is how well you can find and solve new problems on it, but not the tasks formulated by someone else. These are different criteria. In art, tools such as embroidery and mosaic work well if you know in advance what you want to get, but absolutely indecent if you do not know. If you want to reveal an image in the process of writing a picture (what you should do when revealing such complex things as, for example, the image of a person), then you should use a more flexible tool like pencil, ink or oil paints. Of course, tapestries and mosaics are made just like that: first a picture is created, and then only it is copied.

This means that we are unlikely to have a proper comparison of the relative strength of programming languages. We will have exact comparisons, but not correct ones. In particular, studies explicitly aimed at language comparisons are likely to use small tasks and will necessarily use a predefined set of tasks, and therefore will tend to underestimate the most powerful languages.

Reports in this area, although they will be less accurate than “scientific” studies, are likely to be more meaningful. For example, Ulf Wieger from Ericsson conducted a study and came to the conclusion that Erlang is 4-10 times shorter than C ++, and the software development speed on it is proportionally higher:

Comparison of internal projects in Ericsson reveals similar productivity in lines of code per hour, including all phases of development, regardless of the language used (Erlang, PLEX, C, C ++ or Java). Differences in languages ​​- only in the total amount of source code.


This study also clearly indicates that it does not appear in Brooks' book (since it measured only lines of debugged code): programs written in more powerful languages ​​tend to contain fewer errors. This is already quite enough, and probably in tasks such as network switches, this is more important than the programmer’s performance.

Tastes


In the end, you can trust your instinct. What is programming in this language? I think that in order to create a better language you should become hypersensitive to how well the language allows you to think in it, and then choose or develop a language that seems most suitable to you. If any property of the language is inconvenient or restrictive - do not worry, you will know about it.

But such hypersensitivity will result in clumsy languages ​​becoming unbearable for you. I find programming in languages ​​that do not have macros unbearably restrictive, just as if someone accustomed to dynamic typing would consider unbearably restrictive the return to languages, where types should be described for each declared variable and it is impossible to declare a list consisting of elements different types.

And I am not alone. I know many Lisp hackers with whom something similar happened. In fact, the most accurate measure of the relative strength of a programming language could be the proportion of programmers who know a given language who will undertake any work in which this language should be used, regardless of the subject area.

Limitations


Probably many hackers know what it feels like when the language seems restrictive. This is probably the same feeling as when you get stuck in a traffic jam on the street that you want to drive along and you have to make a long detour. You want to say something and language does not allow you to do this.

In fact, a limiting language is not a succinct language. The problem is not that you cannot express something, but that the detour that this language forces you to make is too long. Do this thought experiment: you want to write some kind of program, and the language does not allow you to do it the way you planned, but instead it makes you make it shorter. At least for me this would not be too restrictive. As if a policeman would direct you from a traffic jam onto a shorter road instead of a long detour. Wow!

It seems to me that the feeling of limitedness basically (by 90 percent?) Stems from the fact that you are forced to make the program longer in the language you are writing in, compared to the language in which you think. Boundedness is basically insufficient brevity, so when a language seems to be limiting, it means that it is not short enough.

Readability


The quote I started with also mentions two other qualities: regularity and readability. I don’t really understand what regularity is, and what are the benefits of regular and readable code compared to just readable code. But I think I know what is meant by readability, and it also seems to me that this has to do with brevity.

Here we must be careful with the concepts of readability of a single line of code and the readability of the program as a whole. Only the last is important. I agree that one line on BASIC is most likely more readable than one line on Lisp, but a program written in BASIC will have more lines than the same program written in Lisp. Reading the BASIC program will take more effort.

total effort = effort to read one line * number of lines


I'm not so sure that readability is proportional to brevity, but definitely brevity is a factor in readability (see the formula above). So it hardly makes sense to say that the purpose of the language is readability, but not brevity.

For a user who sees this language for the first time, line-by-line readability means that this language will seem harmless to him. Thus, line-by-line readability can be a good marketing decision, although it is a bad design decision. It is isomorphic with respect to the method of payment in installments: instead of being intimidated by a large deposit, you offer the buyer a small monthly payment. Payment in parts is ultimately unprofitable for him, as well as line-by-line readability - for the programmer. The buyer must make many small payments, just as the programmer must read many readable lines separately.

This ratio existed even before the advent of programming languages. If you read novels and newspaper articles, then your first experience reading an article in mathematics can be frightening: reading one page takes half an hour. Nevertheless, I am sure that the problem is not in the notation, as it might seem at first glance. An article in mathematics is difficult to read because the ideas themselves are complex. If you express the same ideas in prose (as mathematicians did before they thought of a brief notation), then reading them would not be easier, because this single page would turn into a whole book.

In what degree?


Some disagreed with the idea of ​​brevity = strength. I think, instead of arguing whether this is so, it would be more useful to ask to what extent brevity is power? Because it is clear that brevity is one of the main purposes of programming languages. And if not, what is their purpose, and how important are those other functions?

I propose this not to make the discussion more civil. I really want to know the answer. When, if this happens at all, does the language become concise enough?

The hypothesis with which I began was that, except for some pathological cases, brevity is identical to strength. I meant that they will be identical in any language developed by someone, but if someone wants to create a language specifically to refute this hypothesis, then it will probably work out. But I'm not really sure about that either.

Languages ​​But Not Programs


It should be made clear that we are talking about the brevity of languages, not individual programs. Of course, some programs can be written very tightly.

I wrote about this in the book “About Lisp”. In order for the macro to justify itself, it must save many times more space in relation to its own length. If some bulky macro saves ten lines of code every time you use it, and the macro itself consists of ten lines, then you will get savings in lines if you use it more than two times. But this is still a bad move, as macro definitions are more difficult to read than regular code. You may need to use the macro 10 or 20 times before the readability improves.

I am sure that in any language such compromises are possible (although I suspect that the stakes are raised in strong languages). Every programmer has ever seen code that is extremely shortened due to dubious programming techniques.

Thus, it is indisputable - at least for me - that programs can be concise enough. The question is, can the languages ​​themselves be short? Can languages ​​force programmers to write briefly (in elements) at the cost of readability?

One reason it is hard to imagine a too concise language is that if there is an overly compact way of expressing something, then there will probably be a longer way. For example, if it seems to you that using macros or high-level functions in Lisp is too dense, you can write code that is isomorphic to Pascal. If you do not want to express the factorial in the language of Arc as a call to a high-level function,

(rec zero 1 * 1-)

you can also write a recursive definition:

(rfn fact (x) (if (zero x) 1 (* x (fact (1- x)))))

Although I cannot give examples so immediately, I am interested in the question: can the language be too short? Are there any languages ​​that force you to write illegible code? If anyone has any examples, I would be glad to see them.

(Remember: I’m interested in programs that have a high density according to the measure of “elements” described above, but not programs that are short just because separators can be omitted in them and everything has names that are one character long.)

It was first published here .




image
Learn the details of how to get a sought-after profession from scratch or Level Up in skills and salary by taking SkillFactory online courses:




All Articles