
Less is exponentially more - enneff
http://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html
======
munificent
I think as working programmers, we end up torn between two opposing
perspectives with our tools (i.e. programming languages, editors, language
features):

On one side, there's the aesthetic of minimalism. Visualize the master
Japanese calligrapher seated in an otherwise empty room, table before him. One
parchment, one pot of ink, one brush. And he creates the most flawless art one
could imagine. Mastery means removing all artifice, leaving only pure
creation.

On the other side, take a look at your average real workshop: a mechanic's
garage, a woodshop, or an operating theatre. They are filled with tools.
Mastery is knowing a hundred different implements, each carefully designed for
one or a few uses. Mastery means having tamed a thousand tools and knowing
which one is the perfect one to apply to the situation at hand.

Programming languages live on a continuum between these points. Over in Zen
land, you've got Scheme and Go, maybe Smalltalk and JavaScript. Over in
everything-but-the-kitchen-sink territory, you've got Java, C#, Common Lisp,
and C++.

The first image certainly seems cooler: you as code ninja wielding vi and
lambdas with deadly precision. It's the aesthetic of the artist and
intellectual. The second image is blue collar, the tradesman, the kid who took
shop class for four years, the vocational school graduate.

If we accept the second image, that says something deep and maybe unpleasant
about how we look at our work. But, honestly, I think the reality is that
quality professional work often looks like the second picture. Every time I go
to Home Depot and get some random tool that only does one thing (basin wrench,
water heater element remover, you name it), it takes a job that would be hours
of frustration and turns it into child's play, _and the quality of the work is
better._

Simplicity is a virtue worth striving for, but I think it's also valid to want
_tools perfectly suited for certain tasks_. The real art is balancing the two.

~~~
shadowmint
Your metaphor certainly resonates with me, but there are two mixed concepts
here:

1) The 'zen' axis of language syntactic joy.

2) The 'practicality' axis which is a kind of mix of size of the standard
library, availability of 3rd party libraries that do Really Cool Useful Stuff
and the speed of the resulting binary.

Your toolkit isn't really about the zen axis. It's about the practicality
axis, and that's where java with its epic standard library, and c++ with its
insanely huge number of 3rd party libraries are the workshop, and go is the
empty room with a desk.

I mean, the go standard library is amazing (<http://golang.org/pkg/>) but its
missing some of the features you might want if you're say, trying to build a
desktop application on windows...and there just isn't (yet) the 3rd party
support for it.

Professional work is, as you say, strongly tied to the practicality axis.

Yet, its worth noting that there are certainly domains that even now go is a
better and more _practical_ target for applications than C++ or java, with a
comparable runtime speed. Specifically, I'd suggest, cross platform system
level tools and web applications.

It doesn't really surprise me that most C++ programmers haven't jumped to go;
I'd wager most C++ programmers work on applications that don't cross into
these domains.

~~~
krishnakv
IMHO, its not fair to compare Go libraries (at this stage) with the more
mature implementation of libraries in C++ and Java. That will come with
adoption, but even at this early stage, the set of libraries that come with go
offer a lot of power.

Agreed Java came out of the gates with a good (??) desktop programming
library. Google Go's library on the other hand is very web oriented with the
building blocks of http, templating, json all woven in - maybe its a better
approach to take, seeing how desktop programming is fast disintegrating into a
proprietary, incompatible mess with bottle windows (metro) and apple (ios)
locking up their environments.

I agree heartily with the zen metaphor, when programming in Go, I find the
language recedes to the background and allows me to focus on the task at hand.
That's the hallmark of a great language design.

The very very very fast compilation times (you have to experience this to
believe it), helps a lot. Gives it the fast turnaround of a scripting language
without any loss of power/ expressiveness.

~~~
shadowmint
The point I was making is that _right now_ go has a poorer set of 3rd party
libraries than, for example java or c++, and that means that as a _practical
target_ it's not as attractive for people writing _particular types_ of
software.

It's patently absurd to argue that because go > C++ on the 'Zen' scale, that
it's somehow also > C++ on the 'practicality' scale. These two axes are not
totally independent (arguably say, the verbosity of java for example,
decreases its value on the practicality scale) but they're weakly related.

Having a toolkit like QT makes C++ a vastly superior choice to go for a
desktop application, _despite_ the fact that C++ lies somewhere on the dark
depths of hell on the 'Zen' scale.

What I was saying, and agreeing with the OP on, is: Pick your tool for your
problem.

In some cases, that's Go. In some its C++. In some it might be java; but not
having all those tools lying around that people can pickup to use is a major
failing for go.

...and sure, that'll change eventually I'm sure; but it's an entirely valid
complaint _right now_

------
pessimist
Go has some really great features, I've written a few thousand lines in it and
enjoyed it, but there are some strange hangups that the go designers have that
in the end make me think its going to go nowhere.

1\. Rob Pike is immensely proud that the language has no generics, but this
means that in the last 2 years, there isnt a proper implementation of a linked
list that can hold an arbitrary type, or a min-heap, an ordered map, or a
b-tree, or any one of countless data structures that one can take for granted
in every other language. And yes, there are implementations that take
interfaces, but you have to very odd-looking casts to coerce values in and out
of them.

2\. Go - or its testing support - doesnt allow a simple assert or EQUALS
macro, simply because Rob believes everything should be done with if/then
structures. Along with error handling, this makes go tests painful to read.

3\. Idiosyncratic handling of pointers and values, leading to confusion
everywhere and accidental copies and bugs where people pass by value
accidentally because its extremely easy to.

4\. Channels aren't really that useful beyond small programs (IMHO, maybe I'm
wrong), and by making them synchronous any non-trivial go concurrent program
has to reason very carefully to avoid deadlocks.

There are countless similar things. People will put up with these
idiosyncracies for a while but move on in the end.

~~~
enneff
Allow me to respond to your points.

1\. Your characterization of Rob's position on generics is not at all
accurate. The Go team's view, in a nutshell, is that generics would offer some
exciting possibilities for Go (particularly when combined with its concurrency
model) but that it is also extremely hard to do generics well. We have put a
huge amount of work into defining and refining Go, and we don't want to break
it with a bad generics implementation.

There are plenty of "proper implementations" of these collection classes. Your
only criticism of them seems to be that they are not type safe. But it is
trivial to implement a type safe wrapper around such containers, if you desire
it. So the situation is perhaps a little cumbersome, but no worse than C. I
don't think this is enough to doom the language.

2\. This appears to be a matter of taste. You find Go's tests hard to read. I
find them easy to read, as they're not written in some domain-specific testing
language. They're just Go code.

If you need asserts in your Go tests, they're trivial to add with an auxiliary
package, and thanks to "go get" it is trivial to install and use external
packages.

3\. I have carefully reviewed the code of hundreds of new Go programmers (I'm
a Go readability reviewer at Google and work on the open source project) and I
haven't observed the issues you describe here. I sometimes see an initial
confusion about addressability, but it is usually just this:
[http://golang.org/doc/go_faq.html#methods_on_values_or_point...](http://golang.org/doc/go_faq.html#methods_on_values_or_pointers)

4\. I think you're wrong. Think of any time you've written an event loop or
had to rally multiple threads. I'm confident that in most of those cases you
could have done it more cleanly with goroutines and channels.

Finally, look at the state of programming today. Most of the languages and
libraries that people use are riddled with idiosyncrasies. The Go language and
libraries, by contrast, are amazingly regular. This is not just my opinion,
but the feedback that I receive consistently from Go programmers around the
world.

~~~
pessimist
> So the situation is perhaps a little cumbersome, but no worse than C.

Actually, this is not totally true. C has pre-processor and void * which
allows for simple generic data structures with no performance impact. go ties
your hands here since you have to use type-assertions which are not free,
unlike C casts.

> 4\. I think you're wrong. Think of any time you've written an event loop or
> had to rally multiple threads. I'm confident that in most of those cases you
> could have done it more cleanly with goroutines and channels.

Goroutines are great, but synchronous channels are not at all easy to use
beyond simple producer/consumer models.

I'll also note that for both complaints 1 and 2, you think its trivial for
programmers to just do the work, but I though go was all about saving
programmer time?

~~~
krarick
> I'll also note that for both complaints 1 and 2, you think its trivial for
> programmers to just do the work, but I though go was all about saving
> programmer time?

Go is "penny foolish and pound wise", to subvert the maxim.

It is indeed trivial for programmers to just do the work, and in return you
get an amazingly regular system that saves huge swathes of time grappling with
larger issues.

I've noticed this realization occurring to other programmers. It's not at all
obvious until you've written a significant amount of Go code.

------
larsberg
It would be interesting to know if Rob and company would be using the language
if they weren't also the compiler developers.

It's one thing to trust a language with "less" features when you own the
compiler and runtime, but another entirely when you do not. Rob and company
have the backdoor that any time the compiler is not generating code that is as
good as they expect, they can fix it _quickly_! Speaking as a compiler writer
myself (albeit a research compiler, Manticore), ownership dramatically changes
your attitude towards using a language. Optimization limitations become "small
bugs to fix when you run into them" rather than a "reject this tool as
unusable" issue.

~~~
luriel
There seems to be plenty of people that trust Go even if they are not the main
compiler and runtime developers, Canonical, Heroku, the BBC, not to mention
many startups that have completely bet their business on Go:

<http://go-lang.cat-v.org/organizations-using-go>

~~~
pufuwozu
Atlassian is on that list but I know that last year we rewrote our Go code to
Python after our main Go developer left.

~~~
zaphar
I've never understood this kind of action. Go is so small you could hold the
spec in your hand and it's going to be faster and more efficient than python
as well as safer to modify thanks to type safety. If it were haskell, or a
similarly difficult language to wrap your head around, I could see wanting to
rewrite to something easier to understand. But Go has none of those problems.
What could possibly motivate a rewrite?

~~~
eta_carinae
> Go is so small you could hold the spec in your hand and it's going to be
> faster and more efficient than python as well as safer to modify thanks to
> type safety.

I think it's very naive to think that the value of a language in a corporation
is limited to its syntax or compilation speed.

~~~
zaphar
If I had limited my analysis to just those things you would have a point. I
didn't though. errnoh provided the justification OP was missing. The pre Go1
api changes where a very fast moving target so reducing that maintenance
burden was a valid concern. My response was just consternation at the desire
to rewrite something when the language is simultaneously easy to learn, safer
to modify, and probably faster and more efficient at the task than the
language you rewrote it to.

------
btilly
The comment on types reminds me of a very thoughtful comment in _The Structure
and Interpretation of Computer Programming_:

"Developing a useful, general framework for expressing the relations among
different types of entities (what philosophers call ``ontology'') seems
intractably difficult. The main difference between the confusion that existed
ten years ago and the confusion that exists now is that now a variety of
inadequate ontological theories have been embodied in a plethora of
correspondingly inadequate programming languages. For example, much of the
complexity of object-oriented programming languages -- and the subtle and
confusing differences among contemporary object-oriented languages -- centers
on the treatment of generic operations on interrelated types. Our own
discussion of computational objects in chapter 3 avoids these issues entirely.
Readers familiar with object-oriented programming will notice that we have
much to say in chapter 3 about local state, but we do not even mention
``classes'' or ``inheritance.'' In fact, we suspect that these problems cannot
be adequately addressed in terms of computer-language design alone, without
also drawing on work in knowledge representation and automated reasoning."

The next time your complex type hierarchy starts to fragment, you might want
to think about that.

------
ken
For some reason I find this sentence rather amusing:

"Starting point: C, fix some obvious flaws, remove crud, add a few missing
features."

From what I've seen, they've done some good things with this language, and
looking backwards from today, it's clear that C is one of its ancestors.

Yet if I was given a blank sheet of paper with the same sentence, I would end
up with a completely different language. In other words, this reads to me like
shorthand for "Rob, that thing that's in your head, build that" (which is a
perfectly legit thing to say -- I've said it myself).

It's like giving a bunch of people the requirement to fix the "obvious flaws"
of automobiles, and someone draws a convertible, and someone draws an electric
car, and someone draws a motorcycle, and still someone else draws a bus.
Looking backward, you can see where it came from, but looking forward, nobody
can predict where fixing someone else's obvious flaws might lead.

I kind of want to hold a contest where I take some ordinary thing that
everybody uses but nobody loves, and have a bunch of people all design a new
one that just fixes the "obvious flaws"!

------
quatrevingts
> Early in the rollout of Go I was told by someone that he could not imagine
> working in a language without generic types. As I have reported elsewhere, I
> found that an odd remark.

What I find odd is that he makes this statement, but then doesn't explain
which of the following he prefers:

1\. Rewriting algorithms again and again for each minor variation of a data
type

2\. Downcasts everywhere

3\. Contorting code to work with the two magic data structures, array and map

Instead he goes on to rant about type hierarchies, which is awfully non-
sequitur.

~~~
enneff
You don't need to pick one of those three. Maps and arrays cover most cases.
The rest of the time you can implement capabilities on your types (touched on
in the article) and do some type assertions.

The really odd thing about the original statement is that this guy "can't
imagine" working without generics. That is a remark that could only be made by
someone who is fixated on modeling all problems in terms of type systems.

~~~
jbellis
It's not an unreasonable way to view the world, though.

"Show me your code and conceal your data structures, and I shall continue to
be mystified. Show me your data structures, and I won't usually need your
code; it'll be obvious."

-ESR, paraphrasing Fred Brooks

~~~
ericbb
data structure != type

------
eta_carinae
> What it says is that he finds writing containers like lists of ints and maps
> of strings an unbearable burden. I find that an odd claim. I spend very
> little of my programming time struggling with those issues, even in
> languages without generic types.

Rob Pike seems to be doing a kind of programming unlike what most developers
do. I fill, empty, filter and analyze values in containers all the time, and I
suspect I'm not the only one.

> C++ programmers don't come to Go because they have fought hard to gain
> exquisite control of their programming domain, and don't want to surrender
> any of it. To them, software isn't just about getting the job done, it's
> about doing it a certain way. > The issue, then, is that Go's success would
> contradict their world view

I'm disappointed that the only justification that he can find to explain why
C++ programmers are not embracing Go is "C++ programmers don't get it".

~~~
luriel
> Rob Pike seems to be doing a kind of programming unlike what most developers
> do. I fill, empty, filter and analyze values in containers all the time, and
> I suspect I'm not the only one.

I don't think you are disagreeing, there is a reason Go has built in
containers like slices and maps: they are very useful.

Rob said he spends very little time _struggling with those issues_ , it
doesn't mean he doesn't work with containers, just that (in Go) it is not a
struggle, it is rare for you to have to write your own containers, and when
you have to it is not particularly difficult (compared to eg., C).

------
enneff
Here's the video of Rob delivering the talk:
<https://www.youtube.com/watch?v=JE17r3n1kz4#t=53m5s>

IMO it is more compelling when spoken.

------
samth
The claim that wanting to be able to abstract over types is the same as
thinking that programming is about constructing taxonomies is one of the
sillier claims I've seen recently.

~~~
Jare
His claim as I understood it is that the fundamental building blocks should
not be types (what something _is_ ), but functional capabilities (what
something _can do_ ). Type abstractions are fundamentally hierarchical (from
an abstraction to multiple concrete versions), whereas capabilities are
fundamentally about composition (I can do A, B and C).

~~~
Symmetry
_Type abstractions are fundamentally hierarchical_

In C++ or Java they certainly are, but Haskell's type classes, for instance,
are much more similar to Go's interfaces.

~~~
zaphar
I don't think anyone is going to say that Haskell's type classes in any way
fit the traditional notion of a type. It's more the exception that proves the
rule in this case.

~~~
it
I know it's a common saying, but I've never understood how exceptions can
prove rules.

~~~
hardwear
It is a very old saying from when "prove" meant what "test" means now.
Exception is meant in the sense of exceptional, unusual. "The unusual event
tests the heuristic."

------
ilaksh
Its not just that many programmers want more control. Its also the case that
many programmers want more complication. They really prefer the most
complicated and difficult way to do things. They don't trust things that are
easier or simpler. I think that maybe they believe deep down that ease-of-use
versus power is truly a zero-sum game, and you just can't get more of one
thing without giving up some of the other. Also, I think that many of them are
afraid of losing some of their masculine programmer identity if they adopt an
easier way to accomplish things. Also, many of them have invested such an
enormous portion of their life and identity to becoming fluent in all of the
complications that it is nearly impossible for anything to come around that
would make them give up that investment.

But it boils down to the fact that selection of base technologies, like all of
the most important human decisions, is generally a NOT rational process, but
rather an emotional and subconscious one.

One thing that's interesting to me, and I know this will be hard to
buy/comprehend for many Go/C++ programmers, but a similar thing is actually
happening with JavaScript versus CoffeeScript.

Its amazing because the languages actually have the same capabilities and the
syntactical advantages are so obvious.

Here is an example rationalization against the adoption of CoffeeScript from
[http://oscargodson.com/posts/why-i-dont-use-
coffeescript.htm...](http://oscargodson.com/posts/why-i-dont-use-
coffeescript.html) :

`` You really need a transpiled language to save you some time from learning
the right way to write JavaScript in the first place? Learn JavaScript's pain
points and just don't do them.

It's like that C/C++ quote goes:

"In C++ it's harder to shoot yourself in the foot, but when you do, you blow
off your whole leg." \-- Bjarne Stroustrup. ``

~~~
bradleyjg
Some people don't trust black boxes because they have been burned too many
times in the past. I don't want to make this an age thing, but in my
observation the people who are chomping at the bit to jump on the next big
thing are generally those who haven't yet really suffered because of someone
else's mistake.

Cryptography's got the right attitude. Don't use things that are proven to be
broken, but at the same time don't trust anything that hasn't been under the
harsh glare of professional scrutiny for a while.

~~~
ilaksh
I'm 34. I started teaching myself software development when I was seven. I
have done PC assembly, C, C++, OpenGL, Win32, MFC, OCaml, .NET, PHP, Python,
Twisted, AS3, JavaScript, WordPress, CoffeeScript and other types of
programming. I have suffered because of mistakes in the underlying platform
implementation in some cases, but in my experience more often I am suffering
because of fundamental design limitations of the platform.

People move on to the next thing because they know it solves fundamental
engineering problems built in to the platform they are on that are causing
constant problems and they are tired of suffering through that. Such as manual
memory management or traditional threading.

For example, back in my C/C++ days, I worked on a number of projects that were
threaded and manually memory managed. No matter how genius the team members
were we always spent a significant amount of time either guarding against
those types of issues or diagnosing them, or working on Make scripts or other
build-related distractions.

So that was one reason why I moved to C#/.NET many years ago. The advantage of
being able to access source code in open source projects, cost benefit and
lack of vendor lock in moved me away from that.

Or for example my main project right now is based on Etherpad which was
originally written in Rhino which is a Java-based JavaScript. They saved a lot
of lines/characters of code by doing it in JavaScript originally which was
good software engineering since less code means fewer defects and JavaScript
runs on both the browser and server which is also helpful. However, it was
built on Java which has dated overly complicated APIs and Rhino is an inferior
JavaScript engine. And we can't get it to stop freezing up/crashing at random
times, which according to one of the former Etherpad team members is normal.

So we are following the lead of Etherpad and converting the application to be
based on Etherpad Lite which is a running on Node.js which is another next big
thing. There are no threads, so I know that can't cause any freezing. The V8
memory management and code generation is state of the art. The system will use
an order of magnitude fewer resources than the old one. The asynchronous Node
execution model and APIs are obviously superior to Java. At least its obvious
to me.

~~~
batista
> _So we are following the lead of Etherpad and converting the application to
> be based on Etherpad Lite which is a running on Node.js which is another
> next big thing. There are no threads, so I know that can't cause any
> freezing. The V8 memory management and code generation is state of the art.
> The system will use an order of magnitude fewer resources than the old one.
> The asynchronous Node execution model and APIs are obviously superior to
> Java. At least its obvious to me._

All of those assumptions are broken, some more heavily than others...

------
rogerbinns
I'm still of the opinion they made a mistake by not having exceptions. When
programming in Python exceptions are wonderful because they let me put error
handling code in the appropriate place without having to litter all the
intermediary code to where errors happen with error flags. (Panic is not the
same thing.)

The usual complaint about exceptions is "expense", but the same claims can be
made about gc. The Go FAQ is more concerned about people labelling non-
exception things as exceptions (so what?) or that try/except/finally is ugly.
I agree with the latter, but even worse is littering code with if statements
doing the manual equivalent of try/except/finally.

~~~
enneff
The reason we didn't include exceptions in Go is not because of expense. It's
because exceptions thread an invisible second control flow through your
programs making them less readable and harder to reason about.

In Go the code does what it says. The error is handled or it is not. You may
find Go's error handling verbose, but a lot of programmers find this a great
relief.

In short, we didn't include exceptions because we don't need them. Why add all
that complexity for such contentious gains?

~~~
jbellis
I'm with the grandparent. Every language that I've used that was created after
C has included exceptions, and never once have I missed checking errno.

I can understand why, coming from a C++ context, you'd want to avoid them like
the plague, but other languages (Python, Java, Smalltalk, ...) do a good job
of making them a first-class citizen in the language, which saves a LOT of
boilerplate typing. Seeing call stacks implementing a half-assed exception
catching mechanism makes me sad. (Okay, Java only gets half credit here, since
its checked exceptions inflict a different kind of boilerplate, but my larger
point remains.)

Lack of exceptions is half the reason I'm not interested in writing Go code
yet. The other half is that anything that seriously intends to replace C++
does need an escape hatch to allow manual memory management for when the GC's
one-size-fits-all approach is simply a poor fit. For a language whose goal was
explicitly to replace C++, this is an odd place to be tone deaf. I'm
disappointed to see an attitude of "haha stupid C++ programmers don't
understand that programmer efficiency is more important than CPU efficiency,"
instead of realizing that there are valid use cases where you do need to care
about this and addressing them.

Which is unfortunate.

~~~
Marwy
Did you miss the part where he says: "We weren't trying to design a better
C++, or even a better C. It was to be a better language overall for the kind
of software we cared about."

~~~
jbellis
You're missing the forest for the trees. The topic of the article is about how
good was motivated by creating a better language for systems software than
C++, and hypothesizing why it's nevertheless getting more traction with the
scripting crowd than C++ programmers.

"We—Ken, Robert and myself—were C++ programmers when we designed a new
language to solve the problems that we thought needed to be solved for the
kind of software we wrote. It seems almost paradoxical that other C++
programmers don't seem to care."

------
qznc
Hm, to summarize what Go does better than C++:

    
    
      * Easier to learn
      * Faster to compile
    

On the other hand, C++ provides

    
    
      * Better performance
      * Better abstraction
      * Mature tools
    

Well, I can understand why C++ programmers do not switch.

------
rsaarelm
Huh, they actually made Go to replace C++. I always figured it had a
deliberate intent to be a better C.

I find that being able to define your own numeric types and use them as stack-
allocated things that use the standard operations is a pretty big deal in C++.
I guess it depends on what you're interested in programming.

Also, having a high enough level that you can actually try writing a general-
purpose algorithm library without losing noticeable performance to custom-
written versions is something C++ at least tries to make possible. The
template system is hairy enough to make it a bit questionable just how well
you can pull this off in practice though.

Go doesn't attempt either. The arithmetic is what you get in C, implementor-
blessed select types and only regular function syntax for the rest of the
stuff. If you want to work with interesting mathematical constructs and write
in a system-level language, off to C++ you go. The generic algorithms approach
is also pretty much what you get in C with void pointers, with some run-time
type information added in. You can get more of both expressivity and
efficiency if you write your algorithm to handle a specific type, even when
the algorithm doesn't have much that depends on that specific type.

I guess C++ is a different subset of the language for different people.
Operating system programming doesn't involve mucking around with tensors or
quaternions, and it might also involve more hand-tuned choice structures than
an armory of genericizable general-purpose algorithms and data structures. My
take on Go was that it's a really nice-feeling higher-level replacement for C,
and does most everything except the very nitty-gritty hacky raw-memory
juggling better than C, but I run instantly into very obvious stuff I can't do
which I'd want to be doing with C++.

One thing I also found very tricky to do neatly in Go was a programming style
similar to Unix pipes, where you can deploy single or combined general purpose
tools to operate on streams of data. Go does have support for first class
functions, which handles the tool bit and can even do the combining part
(actual pipe characters would need operator overloading though), but the lack
of genericity and a stream idiom kill it. There was the exp/iterable package
that provided something like this using goroutines, but that got deprecated as
non-idiomatic. I don't know if any replacements have shown up.

I do wonder if I'd like my C++ more if it used the duck typing interface thing
from Go though. OO in C++ tends to feel a bit of an awkward fit to me.

------
greggman
Go looks very cool but it solves only a subset of C++ better than C++. For
example, I doubt very much Crysis, Battlefield or Modern Warfare could be
written in Go on consoles assuming Go even existed on consoles.

Similarly I'm not sure how great it is at client side apps where you need
certain code for OSX and different code for Linux and yet different code for
Windows. Or how about iOS and Android games, two places that use lots of C++?

So at least for me, while I'd love to get the benefits of what Go is trying to
achieve, until it solves the problems I personally need to solve it's
unfortunately off my list.

When I am on a project it fits I'm looking forward to checking it out.

~~~
rubashov
I don't see any reason to prefer Go to the D programming language. D achieves
all the major claimed benefits of Go and yet has vastly more abstraction power
and better type safety and error handling. The interest in Go is a mystery to
me.

~~~
luriel
The interest in a language with even more features than C++ is a mystery to
me.

If you read the linked article you will realize that the main benefits of Go
are precisely from "features" that it omits. D takes almost exactly the
opposite approach, and takes C++ and adds even more.

~~~
rubashov
The lack of generic programming in Go is a huge deal. It's vital for modelling
complex systems without a mess of runtime checks, and generally leads to clean
and reusable designs.

    
    
      With D, you can get very close to the generic ideal, "This
      is the last implementation of linear search I'll ever need
      to write." Or binary search. Or stable matching. Or
      Levenshtein distance. I searched around, and it looks
      like D is the only language offering Levenshtein distance
      on UTF strings without copying the input and without
      special-casing per encoding. D just has the abstraction
      power to deal with variable-width entities efficiently
      and within a unified definition (that works with many other
      inputs, such as linked lists of floating point numbers, if
      you want). It's really the last Levenshtein implementation
      I need to write. Now, you may not care about that particular
      algorithm, but there are benefits of that power for many
      structures, algorithms, and design artifacts that might be
      important to you.
    

<http://www.informit.com/articles/article.aspx?p=1621867>

------
billswift
>Less can be more. The better you understand, the pithier you can be.

The one real weakness of this idea is communicating with others, if you don't
share the _same understanding_ you will lose parts of your audience. This is
part of the problem with C++ I have read repeatedly on HN (I don't know C++
myself), that everyone uses a subset of the language, but too many use
_different_ subsets.

~~~
georgemcbay
This is absolutely a problem with C++ and a problem that Go neatly sidesteps
via simplicity.

In my career as a C++ programmer (thankfully, I almost never write C++ code
anymore), I've met lots of people who used it only as C-with-classes, others
who used many more features but avoided templates, others who used templates
but only via the STL, others who went whole-hog with template metaprogramming;
some who use exceptions for basic flow control, others who avoid that but
still use exceptions for exceptional circumstances, some who avoid exceptions
altogether, etc.

Having each person use their own subset of the language is fine and dandy if
you live in an ivory tower and never need to interface with another
developer's code, but of course that is not at all how software development
works anymore and eventually you'll be in a situation where you have two
chunks of C++ code you need to couple together and they have almost completely
alien interfaces to each other (lack of string as a built-in language type
also contributes to this greatly, especially since many people avoided the STL
for so long).

Go makes a lot of these decisions for you in a way such that doing things in
the non-Go way is actively difficult while doing things the Go-way is nearly
painless.

If you come into the language wanting to write it like C++ or any other
language and you insist that it bend to your will, you probably won't like it.
If you come into it with an open mind you start to really appreciate the ways
in which it has made decisions for you. Even if you don't agree 100% with the
decisions it made, the reasons why those decisions were made can always be
reasoned out and the consistency enforced by those decisions is well worth the
learning curve it takes to get used to them (IMO).

------
salimmadjd
I was at the GoSF meetup. It was great seeing Rob talk and I think many of you
are taking this blog post a bit out of context. The gist of his talk was about
the philosophy and history behind creating Go.

For me the talk made me more convinced to switch over to Go. I'm a believer
that makings things simple is a lot hard than making things complex and I
really appreciate the deliberate approach of the Go team regarding adding
features. I really hope they stay true to Rob's philosophy of less is more for
years to come.

------
pubby
I'll believe it when I see it - anyone have examples of well-written Go
compared side-by-side to well-written C++ to show how it is "more expressive"?

Anyway, the benefit to small languages is that it's much easier to design and
reason about a consistent and reusable set of language features. The result is
overall a superior design, but worse in programmer productivity. Saying "less
is more" is just a Turing tarpit.

~~~
luriel
> The result is overall a superior design, but worse in programmer
> productivity.

Go (or its current implementations) might have many deficiencies, but I think
almost everyone that has used it for any minimally sized project will agree
programming it Go is much more productive than C++.

Some quotes about how productive people are with Go: <http://go-
lang.cat-v.org/quotes>

------
dicroce
Less is less, but Less might be a better choice if you're particular problem
doesn't merit the additional complexity of More.

------
anuraj
If only good programming meant usage of this language over that. Unfortunately
language selection has least correlation to program quality. Better practices,
frameworks and above all programmer maturity matters. High time programming
community thought about creative ways to pass knowledge across. Don't we have
enough hammers already?

------
DeepDuh
I'm curious how one can file garbage collection under doing less, especially
for a language intended for systems programming.

~~~
georgemcbay
You might be less curious if you had read and understood the talk. Relevant
text:

"That way of thinking just isn't the way Go operates. Zero cost isn't a goal,
at least not zero CPU cost. Go's claim is that minimizing programmer effort is
a more important consideration."

In a language with closures and Go-style goroutines and channels, the amount
of programmer effort required to manage memory would be absolutely immense
without a garbage collector.

I believe that "less" as Rob Pike means it doesn't have to do with the
complexity of the underlying runtime (though I suspect he'd like that
complexity to be as small as possible while getting the job done), but rather
the amount of complexity the programmer using the language has to worry about
when constructing programs in the language.

~~~
wvenable
> In a language with closures and Go-style goroutines and channels...

Is that also filed under doing less? I believe C/C++ programmers aren't
flocking to Go because it isn't strictly less. Every language that has tried
to replace C/C++ always ends up doing too much. I'd love to see a replacement
for C that solves the obvious flaws but doesn't add to much to the basic
premise.

~~~
_delirium
There are several of those languages too, but they suffer from the opposite
problem: not enough differentiation to overcome the inertia, tool support, and
installed base of C.

The most developed attempt that comes to mind is Cyclone
<http://en.wikipedia.org/wiki/Cyclone_(programming_language)>.

~~~
wvenable
I agree. In the end, it's not really surprising that C/C++ continue on.
Replacements either include too much to be a strict replacement or do too
little to warrant the change.

------
kjhughes
I have a favorable impression of Go after reading this post, however...

The main argument that less is more is essentially the MIT approach of Richard
Gabriel's classic Worse is Better concept. It merits mention.

~~~
chubot
It's not the same argument. Worse is better is about whether it's more
important to have a simple implementation (Unix/C/NJ style), or a simple
interface (MIT style).

This post is arguing about whether it's important to have a lot of features in
a language, or whether fewer features is more powerful.

C++ has a complicated interface and a complicated implementation. So it's
neither NJ or MIT style.

My perception is that Go has a simple interface but relatively complicated
implementation (relative to C). It's actually closer to MIT style, despite
having the Bell Labs/NJ heritage. Examples: garbage collection, segmented
stacks, and goroutine scheduling. Not saying that's good or bad, but the
"guts" aren't exposed as much as in C. Unix and C let all the implementation
details poke out. They have simple implementations but complicated interfaces.

I guess garbage collection should be the canonical example of an MIT style
feature. The interface is much simpler, but the implementation is extremely
complex. And it does poke through that abstraction boundary and bite you.

~~~
luriel
> C++ has a complicated interface and a complicated implementation. So it's
> neither NJ or MIT style.

Yes, in a way C++ is the worst of both worlds.

I'd like to think Go combines from both traditions and comes to a very nice
and useful compromise.

------
acqq
The most useful information about Go until now for me:

It was not made to replace C++, rather, it seems that it grew out of
frustration of using C++ for some specific project inside of Google. That
program needed 45 minutes to compile on a computer cluster!

However, Rob seems to wonder why more C++ users didn't pick up Go, but Python
users did. But I believe it's more than obvious: I'm sure that he still can't
use Go even as the part of the mentioned 45-minutes-on-cluster compiling C++
project. Go is a system, not something that can be _linked_ to the existing
C++ or C or Fortran project. To compare, note that C was made to be able to be
linked with Fortran or assembly.

Moreover, I believe that even if he had all the time of the world for
rewriting the mentioned 45-minute-on-cluster compiling C++ project in Go, his
resulting program would certainly compile faster and most probably "look"
nicer on the line lieve but would execute bad enough that nobody would like to
switch to his variant, just for the speed and memory usage aspects.

And that's all that it's to be said about Go. Good wishes are one thing, but
the execution matters. One the pure performance level, it pays out immensely
to replace some project written in Python with Go, on the "what compiler does
for you" level too. Python is awfully slow whenever the built-in C code inside
of Python and libraries like numpy is not executed, and the errors which you
can catch with compiler are much more convenient than the run-time errors. But
when replacing C or C++, you simply don't get the execution-level control or
memory footprint benefits with Go. "But it's easier to write, especially
concurrent programs" argues Rob. Yes, you can read it for every language in
existence: for people who are used to the language they talk about, when they
write exactly that what they are used to write, it's the easiest language to
write in. Erlang people would tell him that Erlang is easiest to write for
concurrent programs. It's easy to find the scenario where any language is an
optimal one.

But being better or as good as C is not an easy task. The only language which
was often quoted to produce even faster code was Fortran. Not that Pascal
didn't have the possibility to avoid aliasing problems inherent in C, for the
given tasks, numerical computing, Fortran was for enough historical reasons
more convenient than Pascal.

"The determined Real Programmer can write Fortran programs in any language."
<http://www.pbm.com/~lindahl/real.programmers.html> For those who don't get
it, it's a joke: I quote it in order to finish with: For decades, languages
are marketed as the "silver bullets." Go ain't, just like most of them before.
I'm old enough to know, some of the most successful aspects of Go: fast
compilation, clean declarations and reduced syntax were present in the works
of Niklaus Wirth: <http://en.wikipedia.org/wiki/Modula-2>

Wirth was obviously quite right from the start. And Object Pascal programmers
know they had a lot of good sides of Go even twenty years ago. Including not
being forced to have constructors.

~~~
acqq
Now, what would be the ideal language that would be "better than C" in my
opinion? Let's call it X. In my opinion, X would be some modification of C
with the following properties:

\- no headers in C sense -- a limitation that would allow the definitions to
be independent of text-based macros.

\- the compiling/linking speed of ObjectPascal or Go. That area was the most
ignored by "compiler designers" for years, because "hey we're compiler
designers" and "linkers are not sexy, compiler are." In reality, the mentioned
C++ monster that compiles 45 minutes could be reduced to be compiled to 4 and
have all functionality of current C++.

\- the full "linkability" to C. If I link a bunch of X files, I can get one
OBJ which I can link to the C project. Or I can call from X to C. Both must
work. Maybe I would need to link some run-time support additionally, but it
must be enough.

\- having in compiler "the introspective capabilities" as in D. That is fully
ignored by most of compiler writers and I really believe D is on the right
track, especially since Andrei Alexandrescu worked for some of such features.
If at some point I have some expression and compiler know the type of it, I
should be able to query it. If compiler knows the name of something, I should
be able to query it and insert the name in my code! If compiler knows some
dependency, I should be able to know it in the code, if I need it. Etc.

\- built-in ways for decent strings (with counted sizes, not zero terminated),
counted arrays, lists etc. I should be able to use them in the
declarations/implementations without the overheads of the STL monster that it
became. Again I should be able to link the runtime and access elements of
these from C too.

So the logic would be: you can shoot yourself in the foot like with C, but you
can have a "safer subset" (the compiler should have the switch "compile as
unsafe" which would be off, in order to live you the chance to do low level
when you must, but to keep most of the code "clean." When most of the "common"
arrays, strings, maps, trees are part of the language, in most common cases,
the whole programs could be "safe."

Etc. As you see this probably excludes some of cool features of Go like
"segmented stack" and concurrency but it can give something much more
convenient than C++ and still be as fast and "low-level-to-the-last-byte"
usable like C.

I know, it wouldn't appear too creative, it would appear even less
"interesting" than Go but I believe it would make a change: the C basis is
sound, we still need the language that we know that it cleanly maps to the
assembly.

Go is "something above," therefore not so attractive for those that need the
"to-the-assembly" level.

------
ww520
It's pretty cool that GO has "regular syntax (don't need a symbol table to
parse)." But isn't that most languages don't need the symbol table to parse?
Only languages with ambiguous syntax like C++ needs symbol table.

------
james33
Apparently he wasn't talking about the length of the article.

