pgstrata
Succinctness is Power
2

May 2002

3

"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."

4

- Charles Babbage, quoted in Iverson's Turing Award Lecture

5

In the discussion about issues raised by Revenge of the Nerds [blocked] on the LL1 mailing list, Paul Prescod wrote something that stuck in my mind.

6

Python's goal is regularity and readability, not succinctness.

7

On the face of it, this seems a rather damning thing to claim about a programming language.

8

As far as I can tell, succinctness = power.

9

If so, then substituting, we get

10

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

11

and this doesn't seem a tradeoff (if it is a tradeoff) that you'd want to make.

12

It's not far from saying that Python's goal is not to be effective as a programming language.

13

Does succinctness = power?

14

This seems to me an important question, maybe the most important question for anyone interested in language design, and one that it would be useful to confront directly.

15

I don't feel sure yet that the answer is a simple yes, but it seems a good hypothesis to begin with.

3–4

Babbage: "The quantity of meaning compressed into a small space by algebraic signs ... facilitates the reasonings we are accustomed to carry on by their aid."

5–9

In a discussion of Revenge of the Nerds [blocked], Paul Prescod wrote something that stuck with me: "Python's goal is regularity and readability, not succinctness." A damning thing to claim. As far as I can tell, succinctness = power. So, substituting:

10–12

"Python's goal is regularity and readability, not power." Not a tradeoff you'd want — close to saying Python's goal is not to be effective as a language.

13–15

Does succinctness = power? Maybe the most important question in language design. Not sure it's a simple yes, but a good hypothesis to begin with.

2–15

Paul Prescod said Python's goal was regularity and readability, not succinctness. But as far as I can tell, succinctness = power — which makes that a strange thing to brag about.

17

Hypothesis

18

My hypothesis is that succinctness is power, or is close enough that except in pathological examples you can treat them as identical.

19

It seems to me that succinctness is what programming languages are for. Computers would be just as happy to be told what to do directly in machine language.

20

I think that the main reason we take the trouble to develop high-level languages is to get leverage, so that we can say (and more importantly, think) in 10 lines of a high-level language what would require 1000 lines of machine language.

21

In other words, the main point of high-level languages is to make source code smaller.

22

If smaller source code is the purpose of high-level languages, and the power of something is how well it achieves its purpose, then the measure of the power of a programming language is how small it makes your programs.

23

Conversely, a language that doesn't make your programs small is doing a bad job of what programming languages are supposed to do, like a knife that doesn't cut well, or printing that's illegible.

18–21

My hypothesis: succinctness is power, or close enough to treat them as identical except in pathological examples. Succinctness is what languages are for. Computers would be just as happy with machine language; we build high-level languages for leverage — to say (and think) in 10 lines what would take 1000.

22–23

If smaller source code is the purpose, and power is how well a thing achieves its purpose, then a language's power is how small it makes your programs. One that doesn't is doing a bad job, like a knife that doesn't cut.

17–23

Succinctness is what programming languages are for — leverage, saying in ten lines what machine language needs a thousand for. So the power of a language is how small it makes your programs.

25

Metrics

26

Small in what sense though?

27

The most common measure of code size is lines of code.

28

But I think that this metric is the most common because it is the easiest to measure.

29

I don't think anyone really believes it is the true test of the length of a program.

30

Different languages have different conventions for how much you should put on a line; in C a lot of lines have nothing on them but a delimiter or two.

31

Another easy test is the number of characters in a program, but this is not very good either; some languages (Perl, for example) just use shorter identifiers than others.

32

I think a better measure of the size of a program would be the number of elements, where an element is anything that would be a distinct node if you drew a tree representing the source code.

33

The name of a variable or function is an element; an integer or a floating-point number is an element; a segment of literal text is an element; an element of a pattern, or a format directive, is an element; a new block is an element.

34

There are borderline cases (is -5 two elements or one?) but I think most of them are the same for every language, so they don't affect comparisons much.

35

This metric needs fleshing out, and it could require interpretation in the case of specific languages, but I think it tries to measure the right thing, which is the number of parts a program has.

36

I think the tree you'd draw in this exercise is what you have to make in your head in order to conceive of the program, and so its size is proportionate to the amount of work you have to do to write or read it.

26–31

Small in what sense? Lines of code is the most common measure only because it's easiest — in C a lot of lines hold nothing but a delimiter. Counting characters is no better; some languages just use shorter identifiers.

32–34

A better measure is the number of elements: anything that would be a distinct node if you drew a tree of the source — a variable name, a number, a format directive, a new block. There are borderline cases, but most are the same for every language.

35–36

The tree you'd draw is what you make in your head to conceive the program, so its size is proportionate to the work of writing or reading it.

25–36

Lines of code and character counts are easy but wrong. A better measure is the number of elements — the distinct nodes you'd draw in a tree of the source. That tree is what you build in your head to conceive the program.

38

Design

39

This kind of metric would allow us to compare different languages, but that is not, at least for me, its main value.

40

The main value of the succinctness test is as a guide in designing languages.

41

The most useful comparison between languages is between two potential variants of the same language.

42

What can I do in the language to make programs shorter?

43

If the conceptual load of a program is proportionate to its complexity, and a given programmer can tolerate a fixed conceptual load, then this is the same as asking, what can I do to enable programmers to get the most done?

44

And that seems to me identical to asking, how can I design a good language?

45

(Incidentally, nothing makes it more patently obvious that the old chestnut "all languages are equivalent" is false than designing languages.

46

When you are designing a new language, you're constantly comparing two languages-- the language if I did x, and if I didn't-- to decide which is better.

47

If this were really a meaningless question, you might as well flip a coin.)

48

Aiming for succinctness seems a good way to find new ideas.

49

If you can do something that makes many different programs shorter, it is probably not a coincidence: you have probably discovered a useful new abstraction.

50

You might even be able to write a program to help by searching source code for repeated patterns.

51

Among other languages, those with a reputation for succinctness would be the ones to look to for new ideas: Forth, Joy, Icon.

39–44

The metric lets us compare languages, but its main value is as a guide in designing them — comparing two variants of one. What can I do to make programs shorter? If a programmer tolerates a fixed conceptual load, that's the same as asking how to design a good language.

48–51

Aiming for succinctness is a good way to find new ideas. If something makes many programs shorter, it's probably no coincidence: you've found a useful abstraction. The succinct languages are the ones to mine: Forth, Joy, Icon.

38–51

The succinctness test's real value isn't comparing languages but designing them: asking "what can I do to make programs shorter?" is the same as asking how to design a good language — and aiming for shortness is a good way to find new abstractions.

53

Comparison

54

The first person to write about these issues, as far as I know, was Fred Brooks in the Mythical Man Month.

55

He wrote that programmers seemed to generate about the same amount of code per day regardless of the language.

56

When I first read this in my early twenties, it was a big surprise to me and seemed to have huge implications.

57

It meant that (a) the only way to get software written faster was to use a more succinct language, and (b) someone who took the trouble to do this could leave competitors who didn't in the dust.

58

Brooks' hypothesis, if it's true, seems to be at the very heart of hacking.

59

In the years since, I've paid close attention to any evidence I could get on the question, from formal studies to anecdotes about individual projects.

60

I have seen nothing to contradict him.

61

I have not yet seen evidence that seemed to me conclusive, and I don't expect to.

62

Studies like Lutz Prechelt's comparison of programming languages, while generating the kind of results I expected, tend to use problems that are too short to be meaningful tests.

63

A better test of a language is what happens in programs that take a month to write.

64

And the only real test, if you believe as I do that the main purpose of a language is to be good to think in (rather than just to tell a computer what to do once you've thought of it) is what new things you can write in it.

65

So any language comparison where you have to meet a predefined spec is testing slightly the wrong thing.

66

The true test of a language is how well you can discover and solve new problems, not how well you can use it to solve a problem someone else has already formulated.

67

These two are quite different criteria.

68

In art, mediums like embroidery and mosaic work well if you know beforehand what you want to make, but are absolutely lousy if you don't.

69

When you want to discover the image as you make it-- as you have to do with anything as complex as an image of a person, for example-- you need to use a more fluid medium like pencil or ink wash or oil paint.

70

And indeed, the way tapestries and mosaics are made in practice is to make a painting first, then copy it. (The word "cartoon" was originally used to describe a painting intended for this purpose).

71

What this means is that we are never likely to have accurate comparisons of the relative power of programming languages.

72

We'll have precise comparisons, but not accurate ones.

73

In particular, explicit studies for the purpose of comparing languages, because they will probably use small problems, and will necessarily use predefined problems, will tend to underestimate the power of the more powerful languages.

74

Reports from the field, though they will necessarily be less precise than "scientific" studies, are likely to be more meaningful.

75

For example, Ulf Wiger of Ericsson did a study that concluded that Erlang was 4-10x more succinct than C++, and proportionately faster to develop software in:

76

Comparisons between Ericsson-internal development projects indicate similar line/hour productivity, including all phases of software development, rather independently of which language (Erlang, PLEX, C, C++, or Java) was used. What differentiates the different languages then becomes source code volume.

77

The study also deals explictly with a point that was only implicit in Brooks' book (since he measured lines of debugged code): programs written in more powerful languages tend to have fewer bugs.

78

That becomes an end in itself, possibly more important than programmer productivity, in applications like network switches.

54–57

The first to write about this was Fred Brooks in the Mythical Man Month: programmers generate about the same code per day regardless of language. That meant the only way to write software faster is a more succinct language — and whoever bothers can leave competitors in the dust.

58–60

Brooks' hypothesis seems at the very heart of hacking. I've watched for evidence ever since, and have seen nothing to contradict him.

61–65

But nothing conclusive either. Studies like Prechelt's use problems too short to matter. The real test, if a language is mainly for thinking in, is what new things you can write in it — so any comparison meeting a predefined spec tests the wrong thing.

66–70

The true test is how well you discover and solve new problems, not solve one already formulated. In art, embroidery and mosaic work if you know beforehand what you want, but to discover an image as you make it you need a fluid medium — pencil, ink wash, oil. Indeed, tapestries are made by painting first, then copying. (That's the original sense of "cartoon.")

71–73

So we'll never have accurate comparisons of language power — precise ones, but not accurate. Explicit studies, using small predefined problems, will underestimate the more powerful ones.

74–78

Reports from the field, though less precise, are more meaningful. Ulf Wiger of Ericsson found in a study that Erlang was 4-10x more succinct than C++, and proportionately faster: productivity per hour was similar across languages, so what differed was code volume. It also made explicit what Brooks left implicit — programs in more powerful languages have fewer bugs, which for things like network switches matters more than productivity.

53–78

Brooks found programmers write about the same lines per day in any language, so a more succinct language ships faster. But real comparisons are impossible: studies use toy problems, and the true test is what new things a language lets you discover.

80

The Taste Test

81

Ultimately, I think you have to go with your gut.

82

What does it feel like to program in the language?

83

I think the way to find (or design) the best language is to become hypersensitive to how well a language lets you think, then choose/design the language that feels best. If some language feature is awkward or restricting, don't worry, you'll know about it.

84

Such hypersensitivity will come at a cost. You'll find that you can't stand programming in clumsy languages.

85

I find it unbearably restrictive to program in languages without macros, just as someone used to dynamic typing finds it unbearably restrictive to have to go back to programming in a language where you have to declare the type of every variable, and can't make a list of objects of different types.

86

I'm not the only one.

87

I know many Lisp hackers that this has happened to.

88

In fact, the most accurate measure of the relative power of programming languages might be the percentage of people who know the language who will take any job where they get to use that language, regardless of the application domain.

81–83

Ultimately you go with your gut. What does it feel like to program in the language? Become hypersensitive to how well it lets you think, then choose the one that feels best.

84–85

That hypersensitivity comes at a cost: you can't stand clumsy languages. I find it unbearably restrictive to program without macros, just as someone used to dynamic typing can't go back to declaring every variable's type.

86–88

I'm not the only one. The most accurate measure of a language's power might be the percentage of people who know it who'll take any job, in any domain, just to use it.

80–88

Ultimately you go with your gut: become hypersensitive to how well a language lets you think. The cost is you can't stand clumsy languages anymore — the surest measure of power may be who refuses any job without it.

90

Restrictiveness

91

I think most hackers know what it means for a language to feel restrictive.

92

What's happening when you feel that?

93

I think it's the same feeling you get when the street you want to take is blocked off, and you have to take a long detour to get where you wanted to go.

94

There is something you want to say, and the language won't let you.

95

What's really going on here, I think, is that a restrictive language is one that isn't succinct enough.

96

The problem is not simply that you can't say what you planned to.

97

It's that the detour the language makes you take is longer. Try this thought experiment.

98

Suppose there were some program you wanted to write, and the language wouldn't let you express it the way you planned to, but instead forced you to write the program in some other way that was shorter. For me at least, that wouldn't feel very restrictive.

99

It would be like the street you wanted to take being blocked off, and the policeman at the intersection directing you to a shortcut instead of a detour.

100

Great!

101

I think most (ninety percent?) of the feeling of restrictiveness comes from being forced to make the program you write in the language longer than one you have in your head.

102

Restrictiveness is mostly lack of succinctness.

103

So when a language feels restrictive, what that (mostly) means is that it isn't succinct enough, and when a language isn't succinct, it will feel restrictive.

91–94

Most hackers know what a restrictive language feels like: the street you wanted is blocked off and you take a long detour. There is something you want to say, and the language won't let you.

95–100

What's really going on is that the language isn't succinct enough. The problem isn't that you can't say what you planned — it's that the detour it forces is longer. Suppose instead it forced you to a shorter way. That wouldn't feel restrictive. It would be like the policeman directing you to a shortcut instead of a detour. Great!

101–103

Most — ninety percent? — of the feeling comes from being forced to make the program longer than the one in your head. Restrictiveness is mostly lack of succinctness.

90–103

A language feels restrictive like a blocked street forcing a long detour. But if it forced you to a shorter route, that wouldn't feel restrictive — that's a shortcut. So restrictiveness is mostly just lack of succinctness.

105

Readability

106

The quote I began with mentions two other qualities, regularity and readability.

107

I'm not sure what regularity is, or what advantage, if any, code that is regular and readable has over code that is merely readable.

108

But I think I know what is meant by readability, and I think it is also related to succinctness.

109

We have to be careful here to distinguish between the readability of an individual line of code and the readability of the whole program.

110

It's the second that matters.

111

I agree that a line of Basic is likely to be more readable than a line of Lisp.

112

But a program written in Basic is is going to have more lines than the same program written in Lisp (especially once you cross over into Greenspunland).

113

The total effort of reading the Basic program will surely be greater.

114

total effort = effort per line x number of lines

115

I'm not as sure that readability is directly proportionate to succinctness as I am that power is, but certainly succinctness is a factor (in the mathematical sense; see equation above) in readability.

116

So it may not even be meaningful to say that the goal of a language is readability, not succinctness; it could be like saying the goal was readability, not readability.

117

What readability-per-line does mean, to the user encountering the language for the first time, is that source code will look unthreatening.

118

So readability-per-line could be a good marketing decision, even if it is a bad design decision.

119

It's isomorphic to the very successful technique of letting people pay in installments: instead of frightening them with a high upfront price, you tell them the low monthly payment.

120

Installment plans are a net lose for the buyer, though, as mere readability-per-line probably is for the programmer.

121

The buyer is going to make a lot of those low, low payments; and the programmer is going to read a lot of those individually readable lines.

122

This tradeoff predates programming languages.

123

If you're used to reading novels and newspaper articles, your first experience of reading a math paper can be dismaying.

124

It could take half an hour to read a single page.

125

And yet, I am pretty sure that the notation is not the problem, even though it may feel like it is.

126

The math paper is hard to read because the ideas are hard.

127

If you expressed the same ideas in prose (as mathematicians had to do before they evolved succinct notations), they wouldn't be any easier to read, because the paper would grow to the size of a book.

106–108

The quote mentions two other qualities, regularity and readability. I'm not sure what regularity is. But readability I think I know, and it too is related to succinctness.

109–113

Distinguish the readability of one line from that of the whole program — the second is what matters. A line of Basic is more readable than a line of Lisp, but the Basic program has more lines (especially in Greenspunland), so the total effort of reading it is greater.

114

total effort = effort per line x number of lines

115–116

Succinctness is certainly a factor in readability. So it may not even be meaningful to say a language's goal is readability, not succinctness — like saying readability, not readability.

117–121

Readability-per-line means the code looks unthreatening at first — good marketing, bad design. It's isomorphic to paying in installments: a low monthly payment instead of a scary upfront price, a net lose for the buyer, as readability-per-line is for the programmer, who reads a lot of those readable lines.

122–127

This tradeoff predates programming. Your first math paper is dismaying — half an hour on a page. But the notation isn't the problem; the paper is hard because the ideas are hard. In prose, as mathematicians wrote before their notation evolved, the same ideas would grow to the size of a book.

105–127

Readability is also about succinctness. A line of Basic reads easier than a line of Lisp, but the Basic program has more lines, and total effort = effort per line × number of lines. Per-line readability is a marketing trick, like paying in installments.

129

To What Extent?

130

A number of people have rejected the idea that succinctness = power.

131

I think it would be more useful, instead of simply arguing that they are the same or aren't, to ask: to what extent does succinctness = power?

132

Because clearly succinctness is a large part of what higher-level languages are for.

133

If it is not all they're for, then what else are they for, and how important, relatively, are these other functions?

134

I'm not proposing this just to make the debate more civilized.

135

I really want to know the answer.

136

When, if ever, is a language too succinct for its own good?

137

The hypothesis I began with was that, except in pathological examples, I thought succinctness could be considered identical with power.

138

What I meant was that in any language anyone would design, they would be identical, but that if someone wanted to design a language explicitly to disprove this hypothesis, they could probably do it.

139

I'm not even sure of that, actually.

130–133

Some reject that succinctness = power. More useful than arguing yes or no: to what extent? Succinctness is clearly a large part of what higher-level languages are for. If not all, then what else, and how important relatively?

134–136

I'm not asking just to be civilized; I really want to know. When, if ever, is a language too succinct for its own good?

137–139

My hypothesis was that, except in pathological cases, succinctness is identical with power — in any language anyone would actually design, though someone setting out to disprove it could probably manage. I'm not even sure of that.

129–139

Rather than argue whether succinctness equals power, ask to what extent it does — and what else, if anything, languages are for. I really want to know: when, if ever, is a language too succinct for its own good?

141

Languages, not Programs

142

We should be clear that we are talking about the succinctness of languages, not of individual programs. It certainly is possible for individual programs to be written too densely.

143

I wrote about this in On Lisp [blocked].

144

A complex macro may have to save many times its own length to be justified.

145

If writing some hairy macro could save you ten lines of code every time you use it, and the macro is itself ten lines of code, then you get a net saving in lines if you use it more than once.

146

But that could still be a bad move, because macro definitions are harder to read than ordinary code.

147

You might have to use the macro ten or twenty times before it yielded a net improvement in readability.

148

I'm sure every language has such tradeoffs (though I suspect the stakes get higher as the language gets more powerful).

149

Every programmer must have seen code that some clever person has made marginally shorter by using dubious programming tricks.

150

So there is no argument about that-- at least, not from me.

151

Individual programs can certainly be too succinct for their own good.

152

The question is, can a language be?

153

Can a language compel programmers to write code that's short (in elements) at the expense of overall readability?

154

One reason it's hard to imagine a language being too succinct is that if there were some excessively compact way to phrase something, there would probably also be a longer way.

155

For example, if you felt Lisp programs using a lot of macros or higher-order functions were too dense, you could, if you preferred, write code that was isomorphic to Pascal.

156

If you don't want to express factorial in Arc as a call to a higher-order function (rec zero 1 * 1-) you can also write out a recursive definition: (rfn fact (x) (if (zero x) 1 (* x (fact (1- x))))) Though I can't off the top of my head think of any examples, I am interested in the question of whether a language could be too succinct.

157

Are there languages that force you to write code in a way that is crabbed and incomprehensible?

158

If anyone has examples, I would be very interested to see them.

159

(Reminder: What I'm looking for are programs that are very dense according to the metric of "elements" sketched above, not merely programs that are short because delimiters can be omitted and everything has a one-character name.)

142–147

We mean the succinctness of languages, not individual programs, which certainly can be too dense. In On Lisp [blocked] I noted a complex macro must save many times its length to be justified — even one that nets you lines can be a bad move, since macros are harder to read; you might need ten or twenty uses before readability improves.

148–153

Every language has such tradeoffs, the stakes rising with power; every programmer has seen code made marginally shorter with dubious tricks. So individual programs can certainly be too succinct. The question is, can a language be — can it compel code short in elements at the expense of overall readability?

154–156

Hard to imagine, because if there's an excessively compact way to phrase something, there's probably also a longer way. If Lisp's macros feel too dense, write code isomorphic to Pascal — express factorial in Arc as a recursive definition instead of a higher-order call.

157–159

Are there languages that force code that's crabbed and incomprehensible? If anyone has examples, I'd be very interested — dense by the metric of "elements," not merely short because every name is one character.

141–159

We mean the succinctness of languages, not individual programs — those can absolutely be too dense, as a costly macro shows. Can a language force code that's too dense to read? Hard to imagine, since a shorter way usually implies a longer one too.

165

Kragen Sitaker: Redundancy and Power [blocked]

167
168
169
170
161–170

Further reading: Prechelt's seven-language comparison, Gat on Lisp vs. Java, Norvig trying Prechelt's test, Felleisen on expressive power, Sitaker on redundancy [blocked], and the succinct Forth, Joy, Icon, J, and K.

161–170

A set of related links: Prechelt, Gat, and Norvig on Lisp-vs-Java benchmarks, Felleisen on expressive power, Sitaker on redundancy, and the succinct languages Forth, Joy, Icon, J, and K.