Hello, I’m fried fish.
When SHARING knowledge and experience in the Go community, I often heard slang such as “less is more”, “less is more”, “Avenue to simplicity” and “avenue to simplicity”.
Even when discussing Go issues and proposals, some people will use “less is more” to refute or support the argument, which is very interesting. You wonder, where is it from? What does it mean?
Golden words of the source
Such deep-rooted community cultural concepts must be put forward by core people. He was the author of these words:
Anybody recognize that?
Rob Pike, the father of Go.
Rob Pike has mentioned on several occasions the idea that “less is more” is widespread.
Occasions for sharing include:
- In 2012, The Go SF conference was shared with Less Is Graph More, a collection of articles from the earliest public perspectives.
- In 2015, dotGo shared the Simplicity is Complicated, which continuously inculcates culture and shares ideas.
Variations on this idea have spread throughout the industry, forming a unique “culture” of the Go community.
Of course, the community response has been mixed.
speech
Here is a quote from Rob Pike’s “Less Is More”, translated by @Mikespook. I will reorganize, clip, quote, and illustrate so that wheels are not replicated.
The diagram below:
background
This is what I gave at the Go Conference in San Francisco in June 2012.
This is a private lecture. I’m not speaking on behalf of anyone on the Go team, but I’d like to start by thanking them for everything they did to help launch and grow Go.
I also want to thank the Go community in San Francisco for giving me this opportunity to speak.
What surprises me most about Go
A few weeks ago I was asked, “What has surprised you most since launching Go?”
I immediately had an answer: although we want C++ programmers to know Go as an optional language, more Go programmers come from places like Python, Ruby, and very few from C++.
We (Ken, Robert, and I) used to be C++ programmers ourselves, and we designed new languages to solve problems we encountered in the software we wrote.
Paradoxically, other C++ programmers don’t seem to care much about these issues.
Why develop Go
Today I want to talk about what led us to create Go, and why it wasn’t supposed to be this way and we were surprised by the results.
I promise to talk more about Go than C++, even if you don’t know C++ you’ll still be completely on topic.
The answer can be summed up as: do you think less is more, or less is less?
Bell LABS
Here’s a true story as a metaphor. As follows:
- Bell LABS was originally identified with three numbers: 111 for physics research, 127 for computer science research, and so on.
- In the early 1980s, a timely memo stated that as the amount of research we knew was growing, an additional digit had to be added in order to identify our work. So our center becomes 1127.
- Ron Hardin joked, half-seriously, that if we really understood the world better, we could reduce it by one digit, making 127 just 27.
Of course management didn’t hear the joke, or maybe they didn’t want to hear it, but I think there is some great wisdom in it. Less is more. The better you understand it, the more subtle it is.
Keep this idea in mind.
Background to develop Go
C++ compilation wait
Back in September 2007, I was working on a huge Google C++ program (the one you’ve all used) doing trivial but core work.
It took me about 45 minutes to compile on that huge distributed cluster.
C++ new features improved
I received a notice that several people hired by Google to work for the C++ standardization committee would be giving a presentation.
They will show us what improvements will be made to what was then known as C++0x (now known as C++11).
During the hour-long presentation, we heard about 35 features that were already in the works.
There are more, but only 35 features are described in the report. Some features are small, of course, but significant enough to merit reporting.
Others are very subtle and difficult to understand, such as:
- Left and right value references.
- Variadic Templates.
- User-defined data identifiers (User-defined literals).
At this point I asked myself a question: does the C++ committee really believe that the problem with C++ is that it doesn’t have enough features?
To be sure, in another Ron Hardin joke, simplifying the language accomplishes far more than adding features. This is a little ridiculous, of course, but keep the idea in mind.
Experimental language experiment
A few months before this C++ talk, I gave a talk of my own, which you can see on YouTube, about a toy-like concurrent language I developed in the 1980s. This language is called Newsqueak, and it’s a predecessor to Go.
I did this presentation because of some ideas that were missing in Newsqueak, and I thought about them again while working for Google. I was convinced that they would make writing server-side code so much easier that Google would benefit from it.
I actually tried and failed to implement these ideas in C++. It’s so difficult to relate C++ control structures to concurrent operations that it’s hard to see real advantages.
While I admit that I’ve never really mastered C++, pure C++ still makes everything seem too cumbersome. So I dropped the idea.
But the C++0x presentation got me thinking again. One thing that really bothers me (and I’m sure it 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 is also shortsighted, almost certain that hardware will evolve rapidly over the next decade, and it would be foolish to tie the language too closely to today’s hardware.
Go Initial team
After the report we went back to the office. I started another compilation, turned the chair to Robert, and started communicating the key issues.
By the end of the build, we had pulled Ken in and decided what to do.
We’re not going to write C++ anymore, and we — especially I — want to be able to write concurrency easily when we write Google code.
At the same time, we want to drive big programming, which we’ll talk about later.
Go feature Discussion
We wrote a bunch of things on the whiteboard that we wanted, that we needed. Ignoring syntactic and semantic details, the big picture and the big picture are envisaged.
I still have a mind-bending E-mail from that time.
Here’s an excerpt:
-
Robert: The starting point is C, fix some obvious bugs, remove clutter, add some missing features.
-
Rob: It’s called ‘go’. You can make up the reason for the name, but it has a very good basis. It’s short and easy to spell. Tools: GOC, GOL, GOA. If you have an interactive debugger/interpreter, you can call it “go”. The extension is.go.
-
Robert: The empty interface is interface{}. They implement all the interfaces, so this can be used instead of void star.
We’re not portraying everything correctly. For example, mapping array and Slice took almost a year. But most of the important things about this language feature were settled in the first few days.
Note that Robert says C is the starting point, not C++. I’m not sure, but I believe he meant C, especially in the case of Ken.
But the truth is, we didn’t end up starting at C. We started from scratch, borrowing only such things as operators, parentheses, braces, and partial keywords. (And, of course, from other languages we know.)
Anyway, we are now doing the opposite of C++, deconstructing everything, going back to square one and starting again. We are not trying to design a better C++, or even better C. Just a better language for the kind of software we care about.
Eventually, it became a completely different language from C and C++. Each release is getting more and more different.
Go Feature List
I made a list of important simplifications to C and C++ in Go:
- Canonical syntax (no symbol table for parsing).
- Garbage collection (only).
- No header file.
- Clearly depend on
- No cyclic dependencies.
- Constants can only be numbers.
- Int and int32 are different types.
- Case sets visibility.
- Any type can have methods (no classes).
- No subtype inheritance (no subclasses).
- Package level initialization and defined initialization order.
- Files are compiled into a package.
- Global representation at the package level is sequence-independent.
- No arithmetic conversion (constants are assisted).
- Implicit interface implementation (no “implements” definition required).
- Embed (no upgrade to the parent class).
- Methods are defined as functions (with no specific location requirements).
- Methods are functions.
- Interfaces contain only methods (no data).
- Methods are matched only by name (not by type).
- There is no construction or destructor.
- Postincrement and postdecrement are statements, not expressions.
- There is no front increment or front decrement.
- Assignment is not an expression.
- Execute in the order in which the assignment and function call are defined (no “sequence points”).
- No pointer operations.
- Memory is always initialized with zero.
- Fetching address of local variable is valid.
- Methods do not have “this”.
- A segmented stack.
- No static or other type annotations.
- There is no template.
- There is no exception.
- Built-in string, slice, map.
- Array bounds checking.
Aside from this simplified list and some unmentioned trivia, I believe that Go is much more expressive than C or C++. Less is more.
But even that can’t get rid of everything. There is still a need to build the way types work, proper syntax in practice, and the taboo of making libraries interact better.
We also added some things that C or C++ didn’t have, such as slice and map, compound declarations, top-level expressions for each file (an important thing that was almost forgotten), reflection, garbage collection, and so on. And, of course, concurrency.
I can’t imagine not having generics
What is obviously missing, of course, is type hierarchy. Allow me to say a few harsh words about it.
In the first version of Go, someone told me he couldn’t imagine working in a language without generics. As mentioned somewhere before, I think this is an absolutely magical comment.
To be fair, he’s probably in his own way expressing how much he likes what STL does for him in C++. In the light of the debate, let’s take him at his word.
He says writing containers like int lists or Map Strings is an unbearable burden. I think it’s an amazing idea.
Even for 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. Type. Not function polymorphism, not language-based, or anything else, just types.
That’s the detail that stuck me.
Programmers who came to Go from C++ and Java miss working on type programming, especially inheritance and subclasses, and all that stuff. Maybe I’m an outsider to the genre, but I’ve never really 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. Well, you know what? Type hierarchy is classification.
You have to make decisions about which pieces go into which boxes, including the parent of each type, whether A inherits from B or B inherits from A.
Is a sortable array a sorted array or a sorter of array expressions? If you believe that all problems are typology-driven, then you have to make a decision.
I believe it’s ridiculous to think about programming that way. The core is not the ancestral relationship between things, but what they can do for you.
Of course, this is where the interface goes into Go. But they are already part of the blueprint, which is the true Go philosophy.
If C++ and Java are about type inheritance and type classification, Go is about composition.
The eventual inventor of the Unix Pipe, Doug McIlroy, wrote in 1964 (!) It reads:
We should somehow connect messages and data piece by piece, like a faucet and hose in a garden. This is the same approach that IO uses.
This is the approach that Go uses. Go took that idea and took it a big step further. This is a language of composition and connection.
An obvious example is the way interfaces give us to combine components. As long as it implements method M, it can be put in place regardless of what it is.
Another important example is how concurrency connects computations that run independently. There is also an unusual (but very simple) pattern for composing types: embedding.
This is the unique combination technology of Go, which tastes nothing like C++ or Java programs.
C++/Java big programming mode
There is one unrelated Go design I want to mention: Go is designed to help write large programs, written and maintained by large teams.
There is an idea called “big programming,” and somehow C++ and Java dominate the field. I believe this is just a historical error, or an accident of industrialization. But a widely held belief is that object-oriented design can do something.
I don’t believe that at all. Big software does need methodology, but it doesn’t need such strong dependency management, such clear interface abstraction, or even such fancy documentation tools, but it’s not as important as strong dependency management, clear interface abstraction, and good documentation tools. None of this is something C++ does well (although Java clearly does it better).
We don’t know yet, because not enough software is written with Go, but I’m confident that Go will stand out in the big programming space. Time will tell.
Why is Go not loved by C++ programmers
Now, back to the surprising question I raised at the beginning of my talk:
Why did Go, a language designed to destroy C++, fail to win the hearts of C++ programmers?
Joking aside, I think that’s because Go and C++ have completely different philosophies.
C++ is all about solving problems at your fingertips.
I quote this from the C++11 FAQ:
C++ offers a wider range of abstractions, elegant, flexible, and cost-free expression than the huge growth of specially written hand-written code.
This direction of thinking is different from that of Go. Zero cost is not the goal, at least not zero CPU cost. The Go proposition is more about minimizing programmer workload.
Go is not all-inclusive. You can’t get everything built in. You can’t precisely control every minute execution. For example, there is no RAII. Garbage collection can be used instead. There is also no memory free function.
What you get is powerful, but easy to understand, and easy to use to build modules for connecting combinations to solve problems.
This may not end up being as fast, as refined, or as ideologically clear as your solution 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, something too simple:
- Python and Ruby programmers: They moved to Go because they didn’t give up much presentation power, but they gained performance and were dancing 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 is not just about getting the job done, it’s about getting it done in a certain way.
So the question is, does Go’s success contradict their worldview? We should have been aware of this at the very beginning.
People who are excited about the new features of C++11 won’t care about a language that doesn’t have so many features. Even if it turns out the language has more to offer than they thought.
Thank you.
conclusion
I have always been curious about Go’s philosophy of “less is more”. Where is its source and what is its meaning?
During the Spring Festival, I read and sorted it out once. Although the content of the speech was much, it was also more colloquial. But essentially what Rob Pike calls “less is more” is an interesting thing.
The core point is: “Go and C++ concept is completely different, we want to minimize the workload of programmers, its few features, should be able to join the combination to solve problems, more expressive, rather than heap function”.
What do you think? 🙂
If you have any questions, welcome feedback and communication in the comments section. The best relationship is mutual achievement. Your praise is the biggest motivation for the creation of fried fish, thank you for your support.
This article is constantly updated. You can read it on wechat by searching “Brain into fried fish”. GitHub github.com/eddycjy/blo… Already included, learning Go language can see Go learning map and route, welcome Star urged more.
Recommended reading
- Why doesn’t Go support Map concurrency at the language level?
- The three core designs of Go generics, have you learned them?