Go Design Philosophy: Less is more, where did it come from?

煎鱼
中文

Hello everyone, I am fried fish.

When sharing knowledge and experience in the Go community before, I often heard slang words such as: less is more, less is more, the great road is simple, and the great road is always simple.

Even when discussing Go issues and proposals, some people use "less is more" to refute or support the argument, which is very interesting. Everyone will be very curious, where is the source, what does it mean?

Origin of golden sentence

Such a deeply ingrained concept of community culture must be proposed by someone with a core. The author who uttered this sentence is him:

Does anyone recognize it?

He is Rob Pike, the father of the Go language.

Rob Pike has mentioned a similar "less is more" view on several occasions, which is widely circulated.

Sharing occasions such as:

Various variants of this view are widely circulated in the industry, forming a unique "culture" of the Go community.

Of course, from the perspective of community response, there are both positives and negatives.

Speech content

Rob Pike's " Less is exponentially more " is quoted here, the text part @MIKESPOOK translation, I will rearrange, trim, quote, and map here, and I will not repeat the wheel.

As shown below:

background

This is what I (refer to Rob Pike below) gave a talk at the Go conference in San Francisco in June 2012.

This is a private speech. I'm not speaking here on behalf of anyone on the Go project team, but I'd like to start by thanking the team for everything they have done to make Go and grow.

Also, I would like to thank the Go community in San Francisco for giving me this opportunity to speak.

What surprised me most about Go

I was asked a few weeks ago, "What surprised you the most after launching Go?"

I immediately had an answer: although we want C++ programmers to know Go as a language of choice, more Go programmers come from eg Python, Ruby, and very few from C++.

We (Ken, Robert, and I) were C++ programmers ourselves, and we designed new languages to solve the problems we encountered in the software we wrote.

It seems paradoxical that other C++ programmers don't seem to care much about these issues.

Why develop Go

Today I want to talk about what motivated us to create Go, and why it shouldn't surprise us this way.

I promise to talk about Go more than C++, even if you don't know C++ you'll still be completely on topic.

The answer can be summarized as: Do you think less is more, or less is less ?

The Bell Labs Story

Here's a real story as a metaphor. as follows:

  1. Bell Labs was originally identified with three numbers: 111 for physics research, 127 for computer science research, and so on.
  2. In the early 1980s, an expected memo stated that because the research we knew was growing, one more digit had to be added in order to identify our work. So our center becomes 1127.
  3. Ron Hardin joked half-seriously that if we really understood the world better, we could drop a single digit and make 127 just 27.

Of course management didn't hear the joke, or they didn't want to hear it, but I think there's a lot of wisdom in it. Less is more. The better you understand, the more subtle it is.

Be sure to keep this line of thought in mind.

Background in developing Go

C++ compile wait

Back in September 2007, I was doing some trivial but very hard work on a huge Google C++ program (the one you all used).

It took me about 45 minutes to compile on that huge distributed cluster.

C++ new features and improvements

Got a notice that several people employed by Google who work on the C++ standardization committee will be giving a presentation.

They will tell us what improvements will be made in what was then known as C++0x (now known as C++11).

During the hour-long report, we heard things like there were 35 features already planned.

There are actually more, but only 35 features are described in the report. Certainly some features are small, but significant and worth mentioning in the report.

There are also some very subtle and difficult to understand, such as:

  • Left and right value references (rvalue references).
  • Variadic templates.
  • User-defined data identifiers (user-defined literals).

At this point I asked myself a question: C++ committee really believe that the problem with C++ is that there are not enough features ?

Sure, in another Ron Hardin joke, much more to simplify the language than to add features. Of course it's a bit ridiculous, but it's important to keep this line of thought in mind.

experimental language attempts

Just a few months before this C++ presentation, I gave a talk myself, which you can read on YouTube, about a toy concurrent language I developed in the 1980s. The language is called Newsqueak, and it is the predecessor of Go.

I'm doing this report because of the missing ideas in Newsqueak that I've rethought while working for Google. I was convinced that they would make it easier to write server-side code and Google would benefit from it.

In fact I have tried to implement these ideas in C++, but It's too difficult to relate C++ control structures to concurrent operations, which ultimately makes it hard to see the real advantage.

While I'll admit I've never really been proficient with C++, pure C++ still makes everything seem too clunky. So I dropped the idea.

But that C++0x report made me think about it again. One thing that really bothers me (and I believe also bothers Ken and Robert) is that the new C++ memory model has atomic types.

It feels absolutely wrong to add such a microscopic collection of descriptive details to an already overburdened type system. It's also short-sighted, almost certain that hardware will evolve rapidly over the next decade, and it would be foolish to tie languages too tightly to today's hardware.

Go initial team

After the report we went back to the office. I fire up another compilation, turn my chair to Robert, and start communicating key issues.

Before the compilation was over, we had pulled Ken in and decided what to do.

We're not going to continue writing C++, and we -- especially me, want to be able to write concurrency with ease while writing Google code.

At the same time, we also want to go ahead and control the "big programming", which will be discussed later.

Go feature discussion

We wrote a bunch of things we wanted and what they needed on the whiteboard. Syntactic and semantic details are ignored, blueprints and big picture are envisaged.

I also have a mind-blowing email from that time here.

Here is an excerpt:

  • Robert: The starting point is C, fixing some obvious flaws, removing clutter, adding some missing features.
  • Rob: Name it "go". You can make up the origin of the name, but it has a good foundation. It's short and easy to spell. Tools: goc, gol, goa. If there is an interactive debugger/interpreter, it can be called "go". The extension is .go.
  • Robert: An empty interface is interface{}. They implement all interfaces, so this can be used in place of void*.

We don't paint everything correctly. For example, it took almost a year to map arrays and slices. But most of the important things that the language features are settled within the first few days.

Note that Robert said C was the starting point, not C++. I'm not sure, but I believe he meant C, especially in Ken's case.

But the truth is, in the end we didn't start with C. We started from scratch and only borrowed things like operators, parentheses, braces, and some keywords. (And of course it took its essence from other languages we know.)

Anyway, we're doing the opposite of C++ right now, deconstructing everything, going back to square one and starting over. We're not trying to design a better C++, or even a better C. Just a better language for the type of software we care about.

, it became a completely different language from C and C . Every release is more and more different.

List of Go features

I made a list of important simplifications for C and C++ in Go:

  • Canonical grammar (no symbol table required for parsing).
  • Garbage collection (only).
  • There are no header files.
  • explicit dependency
  • No circular dependencies.
  • Constants can only be numbers.
  • int and int32 are different types.
  • Letter case sets visibility.
  • Any type can have methods (no classes).
  • No subtype inheritance (no subclassing).
  • Package-level initialization and a defined initialization sequence.
  • files are compiled into a package.
  • Global expressions at the package level are order independent.
  • No arithmetic conversions (constants are assisted).
  • Implicit interface implementation (no need for "implements" definition).
  • Embedded (no upgrade to parent class).
  • Methods are defined like functions (no specific location is required).
  • Methods are functions.
  • Interfaces only contain methods (no data).
  • Methods are matched only by name (not by type).
  • There are no constructors or destructors.
  • Post-increment and post-decrement are statements, not expressions.
  • There is no pre-increment or pre-decrement.
  • Assignment is not an expression.
  • Executes in the order in which assignments, function calls are defined (no "sequence point").
  • There is no pointer arithmetic.
  • Memory is always zero-initialized.
  • It is legal to take the address of a local variable.
  • Methods don't have "this".
  • segmented stack.
  • No static or other type annotations.
  • There is no template.
  • No exceptions.
  • Built-in string, slice, map.
  • Array bounds checking.

Apart from this simplified list and some unmentioned trivia, I believe that Go is more expressive than C or C++. Less is more.

But even that doesn't throw away everything. There's still a need to build the way types work, the proper syntax in practice, and the taboo ineffable things that make libraries interact better.

We also added some things that C or C++ didn't have, like slices and maps, compound declarations, top-level expressions per file (an important thing that was almost forgotten), reflection, garbage collection, and more. Of course, there is also concurrency.

Can't imagine without generics

Of course the obvious thing missing is type hierarchies. Allow me to make a few foul words about this.

In the original version of Go, someone told me he couldn't imagine working in a language without generics. Like it's been mentioned in some places before, I think this is absolutely magical comment.

To be fair, he's probably expressing his liking for what STL does for him in C++ in his own way. In the premise of the debate, let's take his point first.

He says that writing containers like int lists or map strings is an unbearable burden. I think this is an amazing point.

Even in languages that don't have generic paradigms, I spend very little time on these issues.

object-oriented approach

But more importantly, he says type is the solution to letting go of those burdens. Types of. Not functional polymorphism, not language foundation, or other assistance, just use types.

This is the detail issue that stuck me.

Programmers who come to Go from C++ and Java miss programming that works on types, especially inheritance and subclassing, and all that. Maybe I'm a layman when it comes to genres, but I've really never found this model to be very expressive.

My late friend Alain Fournier once told me that he thought the lowest form of scholarship was classification. So you know what? Type hierarchy is classification.

You have to make decisions about which piece goes into which box, including the parent of each type, whether A inherits from B or B inherits from A.

Is a sortable array a sorted array or an array representation sorter? If you believe that all problems are type-driven design, then you have to make decisions.

I believe it's absurd to think about programming this way. The core is not the ancestral relationship between things, but what they can do for you.

Of course, this is where interfaces come into Go. But they are already part of the blueprint, that's the real Go philosophy.

If C++ and Java are about type inheritance and type classification, Go is about composition.

Doug McIlroy, the eventual inventor of the Unix pipe, wrote in 1964 (!):

We should somehow connect the message data piece by piece, like the faucet and the hose in the garden. This is the same approach used by IO.

This is also the approach used by Go. Go took this idea and took it a big step forward. This is a language about composition and connection.

An obvious example is the way that interfaces provide us with the way components are composed. As long as it implements method M, it can be put in the right place, regardless of what it is.

Another important example is how concurrency connects independently running computations. And there is also an unusual (yet very simple) type composition pattern: embedding.

That's a Go-specific composition technique, and it tastes nothing like a C++ or Java program.

The Big Programming Pattern of C++/Java

There's an unrelated Go design I'd like to mention: Go was designed to help write big programs, written and maintained by big teams.

There is an idea called "big programming" and somehow C++ and Java dominate the field. I believe this is just a historical blunder, or an industrial accident. But a widely accepted belief is that object-oriented design can do something.

I don't believe that at all. Big software does need to be escorted by methodology, but it does not need such strong dependency management, such clear interface abstraction, or even such gorgeous documentation tools, but it is no more important than strong dependency management, clear interface abstraction and excellent documentation tools. , and none of these things C++ does well (although Java does it significantly better).

We don't know yet, as there isn't enough software written in Go, but I'm confident that Go will come out on top in the big programming world. time proves everything.

Why Go is not liked by C++ programmers

Now, back to the amazing question I raised at the beginning of my talk:

Why is Go, a language designed to destroy C++, and has not won the hearts of C++ programmers?

Jokes aside, I think that's because Go and C++ have completely different philosophies.

C++ is that puts all the problems at your fingertips.

I quoted this on the C++11 FAQ:

C++ has a wider range of abstractions, elegant, flexible, and zero-cost expressiveness than the huge increase in specially written hand-coded code.

This direction of thinking is different from that of Go. Zero cost is not the goal, at least not zero CPU cost. Go's claim is more about minimizing the programmer's workload .

Go is not all-encompassing. You can't get everything built-in. You don't have precise control over every nuanced execution. For example no RAII. Instead, garbage collection can be used. There is also no memory release function.

what you get is powerful, but easy to understand, easy to use to build some modules for connecting combinatorial problem solving .

This may not end up being as fast, as refined, or as ideologically explicit as your solutions written in other languages, but it will certainly be easier to write, easier to read, easier to understand, easier to maintain, and more secure.

In other words, of course, a little too simplistic:

  • Python and Ruby programmers: Go to Go because they don't give up much expressive power, but gain performance and dance with concurrency.
  • C++ programmers: Can't switch to Go because they fought hard to gain precise control over their language and don't want to give up anything they've gained. For them, software isn't just about getting the job done, it's about getting it done in a certain way.

The question then is, can Go's success refute their worldview? We should have realized this from the very beginning.

People who are excited about the new features of C++11 don't care about a language that doesn't have as many features. Even if it turns out that the language has more to offer than they thought.

thank you all.

Summarize

I have always been very curious about Go's philosophy "less is more", where is the source and what is the meaning?

I read and sorted it out during the Spring Festival. Although the content of the speech is relatively large, it is also more colloquial. But in essence Rob Pike's "less is more" is a more interesting thing.

The core point is: "Go and C++ have completely different concepts. We hope that the workload of programmers will be minimized, and a small number of features should be able to connect and combine to solve problems. It is more expressive, rather than heap functions."

What do you think? :)

If you have any questions, welcome feedback and exchange in the comment area. The best relationship is .

The article is continuously updated, you can read it on WeChat search [Brain into fried fish], this article GitHub github.com/eddycjy/blog has been included, learn Go language, you can see Go learning map and route

Recommended reading

阅读 2.8k

煎鱼的清汤锅
今天写代码了吗 :-) 博客地址:[链接]
8.1k 声望
12.7k 粉丝
0 条评论
8.1k 声望
12.7k 粉丝
文章目录
宣传栏