
The Go Programming Language, or: Why all C-like languages except one suck. - AndreyKarpov
http://www.syntax-k.de/projekte/go-review
======
antirez
C, _for the level of abstraction it targets_ is an extremely good language,
and this is the reason why it is still alive, and why a lot of big successful
projects are written using C. The problem is its standard library. The "get
this new language" teams should instead focus on how to _incrementally_
improve C. D was a (bad IMHO) attempt, just retry and make it better, a step
after the other. If we will wait the ANSI committee we can all get old with
strcpy().

IMHO one of the few things that should be addressed at language level is that
structures with function pointer members should have a way to be called with
the implicit structure pointer (something like "this") as argument. That's all
we need from OOP for C. This makes you able to do:

    
    
        list *mylist = createList();
        mylist->push(foo);
        mylist->pop();
    

That's what currently you do like:

    
    
        mylist->ops->push(mylist,foo);

~~~
barrkel
I don't think so; I think you also need polymorphism and probably exceptions.
I think GC would also greatly improve expressiveness, because it makes
functional style much easier to implement without redundant copying. But
minimally some kind of polymorphism, and no, discriminated unions aren't
enough - but Go's interfaces would probably do. Also, some way of hiding data
members that doesn't require obscuring casts would be nice too.

The biggest problems I've had with large C codebases are deep assumptions
about data structures, spread throughout. The biggest benefits of OOP, IMO,
come from firewalling off internal details from client code through the use of
an interface; knowing that client code has to call you, rather than simply
follow your internal links, gives you a lot of freedom to change things after
the fact. A polymorphic reference that the client can't dereference and poke
about with gives you that.

~~~
antirez
I think the point is "for the level of abstraction it targets". Add all those
abstractions that are generally a good thing in a perfect world, and
practically you shifted the language enough to be unsuited for many tasks we
use it today.

~~~
ootachi
Polymorphism doesn't have to add runtime overhead. You can achieve
polymorphism without RTTI through code duplication, as C++ templates do. (You
can also use uniform value representations, like C void *, although this is
limited in its applicability.)

~~~
peterwoo
Code duplication is an overhead. Not as bad as RTTI, but static memory
footprint is still important in the embedded/systems world -- sometimes more
so than runtime memory footprint!

~~~
barrkel
You don't need any RTTI or code duplication for polymorphism, so long as you
don't need general support for type-checked downcasts. If you do need type-
checked downcasts, it can be as cheap as a single pointer on antirez's
mylist->ops function table - a pointer pointing to the ancestor function
table.

(Specific support for any single downcast is trivial - just write a function
for the function table, typed appropriately and implemented appropriately.)

------
chimeracoder
If C isn't suitable for projects with more than 10K lines, then praytell, what
language should my kernel be written in?

I've been meaning to try Go for a while (the fast compile times alone
intrigued me), but this type of post really just puts me off - if you're
telling me that C isn't suitable for large projects, then that tells me you
may not know C well enough to make that judgement.

~~~
technomancy
> If C isn't suitable for projects with more than 10K lines, then praytell,
> what language should my kernel be written in?

The Xen hypervisor (which shares a lot of characteristics with an OS kernel)
is written in OCaml, which seems to have proven a good choice in practice:
<http://gazagnaire.org/pub/SSGM10.pdf>

~~~
plantain
Not the hypervisor, just the management tools.

------
rpearl
Unfortunately, the author seems to have misconceptions about a variety of
things.

> projects with more than 10k LOC.

Other comments have discussed this. Linux kernel: ~4million lines. Compilers,
interpreters, and so on... all well above 10k LOC. While C is not the best
language for such things, by no means is it unmanageable.

> But when you try to do the modern funkiness of dynamic languages (lambda
> functions, map/reduce, type-independence, ...)

All of the features can be used in much stronger type systems than C++ gives
you. ML-family languages have all these features and are strictly type.d

> Javascript Javascript's whacky semantics suck, that's for sure, but for a
> dynamic language that's par-for-course anyway. I don't really understand his
> argument about embedding. Why is that relevant? Java and C# are not
> embeddable either. ...So?

~~~
scriptproof
I had the same feeling. Node.js is a part of webOS, that uses JavaScript as
programming language, and Tizen too.

------
cobrausn
_So while C may be as lightweight as it can get, it's not really suitable for
projects with more than 10k LOC._

I believe John Carmack would have something to say about this.

<http://en.wikipedia.org/wiki/Id_Tech_3>

~~~
cperciva
For that matter, _libc_ is considerably more than 10 kLOC (on FreeBSD 9.0,
it's about 140 kLOC), and it's hard to think of a more stereotypical block of
C code than that.

~~~
mynegation
It is stereotypical library but not stereotypical software project per se.
Functions in libc have (by design) very strict interface and little data
interdependency.

I would say SQL or HTTP server or game or a word processor where you have to
retain sizable chunks of data in memory for longer periods is a better example
of big C project. And that's where lack of automatic memory management and
data abstraction in C makes it hard.

~~~
gaius
Oracle is written in C.

------
LeafStorm
> What makes me stay away from it is the non-free nature. Yes, there is Mono,
> but I wouldn't like to base my stuff on a language that is there because of
> Microsoft's benevolent permission which it could turn into patent-lawsuits
> any time. We all know the tricks that company (well, actually any large
> company) has up its sleeves.

Microsoft has standardized C# and the CLR through ECMA, and issued a promise
stating that they will not assert their patents against alternative
implementations thereof. Non-standardized APIs like ADO.NET, ASP.NET, and
System.Windows.Forms are not protected by that promise, but Mono discourages
their use anyway and if they had to remove them, it would not affect the C#
compiler or CLR in any way. So this is not a legitimate reason to avoid using
Mono, unless you (a) need to use the non-standardized Microsoft APIs or (b)
are Richard Stallman.

~~~
noveltyaccount
Agree. I would have preferred he kept politics out of the argument and
actually reviewed _the language._

------
boyter
The Java comments are wrong IMHO. Yes it has some legacy cruft. Yes you can
import 10 million libraries and build abstractions on abstractions. Yes you
can architect your application to resemble a Rube Goldberg machine.

Guess what? Those same points apply to an language. Heck the evolution of a
Python programmer <https://gist.github.com/289467> currently on the front page
which does the same thing for Python which is usually pretty clean. Even PHP
which is mentioned as the alternative can quickly become a spaghetti ball mess
of imported code and shared snippets.

I don't love Java, but for certain classes of problems it is an excellent
choice and to discount it based on a wrong perception just shows how shallow a
technologist you are.

~~~
batista
_The Java comments are wrong IMHO. Yes it has some legacy cruft. Yes you can
import 10 million libraries and build abstractions on abstractions. Yes you
can architect your application to resemble a Rube Goldberg machine. Guess
what? Those same points apply to an language._

Potentially, yeah, but guess what? It does not happen in every language.
That's why it's most often brought up for Java. Because it's not just the
potentiality that matters, but the actuality too. In other words, it also
takes a culture, and Java very much has that kind of culture.

 _Heck the evolution of a Python programmer<https://gist.github.com/289467>
currently on the front page which does the same thing for Python which is
usually pretty clean_

See? Usually, as in, "Usually pretty clean", is the key word here. Whereas
Java program design is usually pretty convoluted.

And the "Evolution of a Python programmer" is mostly a joke, meant to show the
tendency of some Python types to use some newer/cooler/functionaler (sic)
features in place of more simple and readable ones. It's not what commonly
happens in Python projects though.

------
DanWaterworth
Just from the title I can tell this is going to present a completely
objective, well thought-out, unbiased appraisal.

~~~
noveltyaccount
This is Hacker News. You have to have a conclusion or command in your title to
get upvotes. "Why the cloud is wrong for your business." "Why your language
sucks." "SaaS-de-jour, we have a problem."

~~~
cageface
It hasn't always been this way but lately it sure seems that you need a
sensational, controversial headline to make it to the front page.

------
tmcw
I wish people writing things like this would write about the positive aspects
of the language first. Are you really going to convince people who like Java
that Java is bad, in one paragraph? And, do you want to just annoy everyone
with your opinions before you get to the neat facts you want to convey?

Positive first, negative second, or better yet, you understand the negative
argument through the positive.

------
sbov
> Go has no exceptions.

I'm not a fan of the verbosity of error handling with exceptions either. It is
particularly bad for fine grained error handling.

However, I do like that the default state of a non-handled error is to
propagate and eventually crash the thing rather than continue with errors that
may subtly corrupt things. I haven't used Go, but from the explanation of
error handling Go seems to do the latter rather than the former (please
correct me if I'm wrong).

In most languages, exception handling doesn't seem designed for fine grained
error handling, which makes one not want to use it for that. Rather than
complain about the verbosity of their methods, why not try to fix the issue
with a less verbose method?

E.g. something like: handle := openSomeFile() catch err

Or ignore it if you want, letting it automatically propagate: handle :=
openSomeFile()

~~~
casualsuperman2
In Go, the accepted way to report errors is to take advantage of multiple
returns, such as:

    
    
       result, err := somePotentiallyFailingFunction()
       if err != nil {
          // Try to recover here
          ...
          // Not recoverable?
          panic()
       }
    

And this call to panic works the way you prefer. Note that doing the
following:

    
    
       result := somePotentiallyFailingFunction()
    

won't compile since the number of values on the left doesn't match the right,
so if a function can fail and returns an error, you will know. If you do
something like:

    
    
       result, err := somePotentiallyFailingFunction()
    

And then never check err, it's actually a compile-time error, which enforces
error checking, to a point. What's next is the kind of thing you don't like,
and it's poor style.

    
    
       result, _ := somePotentiallyFailingFunction()
    

This assigns the error to _, which causes no errors if you don't use it.

Hope this clears some things up.

~~~
klon
Ok but exceptions also give you alot of context about the error like exactly
where it occured. How is that handled in Go?

~~~
ericbb
The error type is an interface. You can return values that contain contextual
information as long as the error value you return has an Error() method
returning a string.

    
    
        type ParseError struct {
            line int
        }
    
        func (e ParseError) Error() string {
            return "Parse error at line: " + fmt.Sprint(e.line)
        }
    

Note: The current release may vary slightly on the details. I'm using a pre-
release build. But older versions are similar.

~~~
casualsuperman2
And then in the code for handling the error, you can do

    
    
       switch err.(type) {
          case db.IOError:
              // Database exception here
          case io.FileNotFoundError:
              // File exception
          default:
              // Pass it to our caller for them to handle.
              return nil, err
       }
    

Which gives you the ability to selectively catch errors based on type.

------
myhf
_I wouldn't like to base my stuff on a language that is there because of
Microsoft's benevolent permission_

So, he chooses a language that is there because of Google's benevolent
permission.

~~~
hammersend
Go has been released with a BSD-style license including patent grants. If
Google dropped it tomorrow they couldn't stop anyone else from just picking
right up where they left off.

<http://golang.org/LICENSE>
<http://code.google.com/p/go/source/browse/PATENTS>

------
dhconnelly
I hope nobody reads this, is irritated by the listed criticisms of other
C-like languages, and decides to avoid Go. Go is a very well-designed
language. Instead of piling on features, they have optimized for practicality
and productivity. After reading "The Practice of Programming", so much of the
language is obvious.

------
LVB
At work we have tools that automatically concatenate the lines of our .c files
into one giant line of code. That helps us get around the pesky 10K LOC limit.

------
_delirium
Imo the 'Rant about C-oid languages' part of this article is a bit weak
(though I agree with some of it), but the 2nd half of this article is actually
a pretty good rundown of Go features.

------
tomjen3
Actually, all languages suck because there are benefits and tradeofs to every
design decision -- cross compitable binary format means JIT compilers, garbage
collection means more wasted memory, etc. It is all tradeofs.

------
sek
<http://news.ycombinator.com/item?id=2631964>

~~~
why-el
Thanks. I was starting to wonder why this is not generating as many comments
as it normally would have for this type of articles.

------
barrkel
No, I have never written exception-handling code like that mocked in this
article. There's a strong correlation between uses of 'catch' and the
probability that you're using exceptions incorrectly. Go's lack of exceptions
is probably what pushes me away from it most strongly.

~~~
tsotha
That's my take as well. Most of the code I write doesn't attempt to recover
from error conditions. I would say at least 85% of the time I want the program
to exit with enough information that I can tell what happened. So I propagate
the exceptions up to the top level. Nothing could be easier.

This may all be a function of the environment in which my code runs, but I
certainly have no interest in going back to my C days when 95% of the source
was devoted error handling.

------
dkhenry
I really like some of the ideas in Go however it still hasen't hit that
critical mass that languages need to hit to really make it in the crowded
world of programming languages. This is going to be even more difficult for Go
then it was for Python or Ruby since they both can serve very well as
prototyping language or glue languages. As a systems language Go needs to be
able to gain traction from nothing.

~~~
drcube
It just needs an OS to go with it. I think Rob Pike should port Plan 9 to Go.

------
robot
__dynamic_cast <MyData _> (funky_iterator<MyData
&const_>(foo::iterator_type<MyData>(obj)) Yeah. Right. Don't get me wrong, I
love templates, but contemporary C++ using STL looks like a classic case of
the "If all you have is a hammer"-syndrome. GCC had to implement special
diagnostic simplifications just so you can actually find out that that 5-line
error message was a simple const'ness mistake when using a std::string method.
Even worse, they can be slow as hell. Ever waited for Boost to compile? Good
idea, bad realization. __

I have been programming (in C) for 12 years, and when I see something like
this I still get a shivering feeling. How can one design such a shitty
programming language like this?

~~~
cageface
Every language has its pathological corner cases. Modern C++ using the STL is
almost as terse as modern dynamic languages but runs 100x faster.

~~~
j_baker
I would argue that C++ _is_ a pathological corner case.

~~~
cageface
Even Stroustrup has said there's a cleaner, simpler language within C++
struggling to get out. But C++11 is a big step toward that language and C++ is
still the go-to language for a large class of applications for good reason.

------
simonh
One concern I have with garbage collected system programming languages is GC
pauses. I have worked with several java applications that were simply not
capable of handling fast, continuous, time critical processing tasks because
every now and then they would pause for garbage collection. Most of the time
they were fine, but suddenly you'd get brief but unacceptable drops in
performance. Does anyone know if go is likely to suffer from this?

~~~
4ad
Currently, there is a world stop, yes. The garbage collector is parallel, but
not concurrent. A concurrent garbage collector would make that disappear. How
bad it impacts you depends on the workload, personally I've never felt it.
YouTube uses Go[1] and mentioned[2] world stop is significant in their case,
but tolerable.

[1] <http://code.google.com/p/vitess/>

[2] [https://groups.google.com/forum/?fromgroups#!topic/golang-
nu...](https://groups.google.com/forum/?fromgroups#!topic/golang-
nuts/U5ilNZpXzNU)

------
canop_fr
About this point :

> What's even better: you can put labels on your nested loops and break out of
> multiple levels using them. Finally!

This is possible in other languages, too, even if it's a little known fact.

For example in java :

    
    
        ext: for (int i=0; i<4; i++) {
            System.out.println("ext "+i);
            for (int j=0; j<4; j++) {
                System.out.println(" in "+j);
                if (j==2) break ext;
            }
        }

------
jganetsk
_So, what's fundamentally wrong with JS? Not a lot._

At this point the article lost all credibility with me.

~~~
grannyg00se
Some of the implementations in JS went wrong, but fundamentally it really
doesn't have anything horrible going on for what it's meant to do.

Unfortunately some of the implementation details do allow for seriously
horrible code and some seriously horrible traps. But if you can clear the fog,
and use "the good parts", it's actually pretty nice.

As for the article, I think it's very well written and seems to have a good
overview of the language. Also, the author seems to have an above average
experience level in an above average number of programming languages (guessing
here), so it might be worth a read.

~~~
jganetsk
I am not talking about any APIs in JS or any "implentation in JS". JS, the
language, as specified, is wrong at the core. It has a lot of insensible
semantics. It's not even at a local maximum. I could just write a list of 10
changes to the language right now that would spur near-unanimous agreement of
benefit with no downside.

~~~
jvrossb
Go for it.

~~~
spand
There is a site dedicated to collecting them but I cannot find it atm. This
one does a decent job however:

<http://bonsaiden.github.com/JavaScript-Garden/>

------
dustingetz
> One reader detailed the history of Pythons ternary operator

i'd love to see this

------
donaq
Minor nitpick: I think for is a special case of while more than while is a
special case of for.

------
mahmud
Why is he grouping JavaScript with the "C-oid languages"? Not even close!

------
agrover
ctrl-F Rust

...nothing? ok here: <http://en.wikipedia.org/wiki/Rust_language>

------
Abscissa
"[Issue 9] is a C-like language...It is intended to be a systems programming
language..."

What? Google's Issue 9 is neither a C-like language nor a systems language.

~~~
Abscissa
Figures this would get downvoted for not blindly buying into the propaganda:
The syntax is clearly not C-style, that's just plainly-apparent. And just
because a language is natively-compiled doesn't make it a systems language.

