
In praise of Go or "Why I moved from Python and C++ to Go" - BarkMore
http://groups.google.com/group/golang-nuts/browse_thread/thread/7a980dfc568a54f2#
======
megaman821
The only thing I could see myself leaving Python for is Haskell.

Go seems to fall into a very small niche. The inclusion of a GC means it is
not appropriate for a lot tasks that C/C++ are suited for. Also, it is verbose
enough where you can't bang out stuff as fast as in Python/Ruby.

~~~
kjksf
Go, today, is a niche language by usage but is not niche by features.

It's designed as a server-oriented (i.e. aimed at a still growing programming
category) language that is close in syntax to C/Java (i.e. already familiar to
many), almost as easy to write in as Python/Ruby (both very successful, non-
niche languages) but order of magnitude faster and much memory efficient that
either.

As a bonus it has much better concurrency support.

It's designed for the same "niche" that Python/Ruby/Java serves on the server,
with many important improvements over them.

Having written code in Python and Go, Go seems to me an improvement over
Python in many important areas (speed, memory efficiency, concurrency) and the
parts that are not as good are both not as important and not significantly
worse (static vs. dynamic typing is a toss (it's nice not to declare types but
it's also nice if compiler tells you about a type mismatch typo that Python
will only complain about at runtime), Python still has slightly cleaner syntax
etc.).

I didn't experience Go being more verbose than Python to a degree that it
mattered. In some aspects the syntax is actually less verbose (Python class
require more typing than Go interfaces).

Go is still a young language and young implementation. On one hand it means
it's anyone's guess whether it'll become non-niche at some point but at the
same time I'm pretty sure at year one both Python and Ruby were much less
polished and much less popular than Go is at the same stage.

Personally, I'm bullish on Go and if I were writing server side code, I would
use Go (even though at the moment I know Python better).

~~~
alnayyir
>As a bonus much better aligned with today's multi-core reality than Python or
Ruby.

Not substantially. It made the concurrency decisions for you ahead of time,
and if you need a different concurrency model, you're up shit creek.

> but order of magnitude faster and much memory efficient that Python or Ruby.

So is my Radio Flyer Wagon. You still can't do systems programming, embedded,
high performance, or real-time work with it.

I know too much about C and the constraints it works well in to believe Go is
anything but awkwardly crammed between two realms of programming.

A language that forces its own GC upon you (note that you can have GC in
C/C++, you merely have to choose one), and its own concurrency model upon you
without giving you at least a couple choices is not a well designed language.

Even Clojure gives you a couple ways to approach concurrency, and it doesn't
even make the same claims as Go has.

I don't know a single person who's done substantial systems programming who
takes Go seriously in terms of their field.

Not a single one.

~~~
kjksf
> Not substantially. It made the concurrency decisions for you ahead of time,
> and if you need a different concurrency model, you're up shit creek.

It's not true. I'm not sure what concurrency models you feel you need but
let's go through the most popular ones. There's event based programming which
is essentially single-threaded and predicated on structuring your code around
poll/kqueue/whatever loop. You can do that in Go since you can call any OS
syscall from Go. It just leads to awkward code.

There's shared memory multithreading with locks to protect data structures.
You can do that in Go (except you use goroutines, which are multiplexed into
OS threads by Go scheduler, instead of using OS threads directly as in C).

And then there's Go's prefferred (but not exclusive) solution of
channels/goroutines and idea of sharing memory by communicating (as opposed to
communicating by sharing memory as in threads/locks based model).

What concurrency models are available in C or Python or Java that you can't do
in Go?

> So is my Radio Flyer Wagon. You still can't do systems programming,
> embedded, high performance, or real-time work with it.

As a rebuttal (?), it doesn't follow. As to your point, your definition of
systems programming is different from that used by Go designers, since they
are very insistent on calling Go a systems programming language. Please
clarify what kind of systems programming you can do in C/Java that you can't
do in Go?

As to high-performance: I don't follow. It's fast. What kind of high
performance programming you can't do in Go that you can do in C or Java?

As to embedded - sure that niche is owned by C. How is it different from
Python or Java and how does that make Go a niche language?

The same goes for real-time where real-time systems are even more niche and
are as much a property of the OS as it is of the language. You can't do real-
time in any language on stock Linux kernel given that kernel can pre-empt any
application at any time for any period of time.

You make a lot of statements but nothing concrete enough to support them.

I've shown that in Go you can use 3 concurrency models, 2 of which are
currently most popular in the C/Java worlds.

As to systems programming - you don't provide a definition or examples of what
kind of programs do you consider as systems programming so it's hard to argue
at that level.

Does a web server qualify? (you can write one Go).

Would a distributed database like HBase qualify? Even though one hasn't been
written, HBase is Java and there's nothing that you can write in Java that you
can't write in Go, with potentially better performance due to compilation to
native code and more efficient memory usage.

~~~
swannodette
goroutines sound a lot like private queues in Apple's GCD. In their
documentation they are quite clear stating that in performance critical code
... surprise ... they might be a bad fit.

------
WalterBright
I don't see where he got the impression that D is not actively maintained. See
<http://www.digitalmars.com/d/2.0/changelog.html>, which is the record of
frequent, active and extensive updates.

~~~
andralex
Also traffic in the digitalmars.D forum (the main hangout of D developers and
users) is roughly twice the traffic on go's mailing list.

------
contextfree
"- It is "garbage-collected" (which is uncommon for a compiled language: The
only other example is "D") "

wat?

~~~
silentbicycle
Don't let the facts get between you and faint praise!

Also: Common Lisp, Scheme, Erlang, SML, OCaml, Haskell, Lua, Prolog, and Java,
and no doubt numerous others.

For all of the above, many (if not most) implementations compile natively.

~~~
stcredzero
Something which has been neglected, but which has clearly shown its value in
VMs is _the information gained by runtime tracing._

We should make this more available to the programmer! It should be possible
for a programmer to highlight a section of code in an IDE and choose "Apply
Trace," whereupon the IDE will apply static type annotations based from saved
runtime trace information. The IDE should be also able to present the same
information as profiling data to let the programmer quickly home in on the 15%
or so of the app which is most performance critical. Using techniques like
this should let us get C-like speeds from many dynamic languages.

(Admittedly, this sort of thing would also be highly dangerous. One couldn't
apply such semi-automated annotations in ignorance. This could also break
otherwise correct programs.)

~~~
silentbicycle
Directing programmers to hotspots based on programming info is pretty
reliable. In your case, it depends on how confident the annotations are. The
Self papers have a lot about that - JIT compilers can nonchalantly make
riskier optimizations, because they can also easily undo them.

~~~
stcredzero
My idea is that the programmers can add expert knowledge and human
intelligence into the mix. They have the ability to just let the VM know:
"Okay, in this part these things are always going to be _this type_ and things
go like that, so just go to town and optimize the bejesus out of it!"

In other words, a good programmer should be able to just let the VM know ahead
of time what's up in critical sections of stable production code. Even better,
we should be able to combine datasets from many different runs of many VM
instances! This sort of technique would allow us very high degrees of
confidence for things like web apps in server farms, where getting 10's of
thousands of runtime tracing datasets would be easy to do.

This is where a dynamic language with optional type annotations would really
shine.

~~~
xiongchiamiov
Sounds like how some people use Cython.

Snippet from [0], which is unfortunately temporarily down (I got to it through
Google Cache[1]):

    
    
      cpdef double integrate_f(double a, double b, int N):
      	cdef double dx, s
      	cdef int i
      
      	dx = (b-a)/N
      	s = 0
      	for i in range(N):
      		s += f(a+i*dx)
      	return s * dx
    

[0]: <http://www.behnel.de/cython200910/talk.html>

[1]:
[http://webcache.googleusercontent.com/search?q=cache:7NvoUHh...](http://webcache.googleusercontent.com/search?q=cache:7NvoUHhaxRkJ:www.behnel.de/cython200910/talk.html&hl=en&strip=1)

------
grovulent
Having picked up python as my first programming language earlier this year I
am always really surprised to hear how so many programmers hate the
indentation.

I don't ever have indentation errors - or if I do, they aren't ever of a sort
that pyscripter can't spot them.

Must be a what-you're-used-to thing...

~~~
FraaJad
"So the danger to paste stuff at the wrong indent level is far less than in
Python. "

I would argue that this is actually a feature of the language. This "danger"
actually forces the programmer to read through the code he is pasting by
indenting.

Also, how many pairs of source code fragments share the same variable names?
This argument is quite shallow.

~~~
yesimahuman
The biggest error I have with pasting is that the pasted code uses spaces
where I use tabs. They look like the same indent level but they are not.

A good old ggVG= solves that though in vim

~~~
Daishiman
:retab is your friend.

~~~
jeberle
:set expandtab | retab

------
kingkilr
> "It is only superficially object-oriented (no classes, no inheritance, just
> interfaces) so it is more transparent"

What does that even mean?

~~~
BarkMore
From the FAQ: " Although Go has types and methods and allows an object-
oriented style of programming, there is no type hierarchy. The concept of
“interface” in Go provides a different approach that we believe is easy to use
and in some ways more general. There are also ways to embed types in other
types to provide something analogous—but not identical—to subclassing.
Moreover, methods in Go are more general than in C++ or Java: they can be
defined for any sort of data, not just structs."
[http://golang.org/doc/go_faq.html#Is_Go_an_object-
oriented_l...](http://golang.org/doc/go_faq.html#Is_Go_an_object-
oriented_language)

The lack of type hierarchy makes code easier to understand.

~~~
jamesaguilar
Also, an "interface" is more of an enforced duck type annotation than an
interface or ABC in Java or C++ terms respectively.

~~~
aaronblohowiak
IIRC, the duck-type mode uses implicit interface creation but you can force an
explicit interface if you want (please correct me if i am wrong.)

~~~
BarkMore
Interfaces are explicitly defined in Go as they are in Java. The difference is
that you do not declare the interfaces implemented by a type. If a type has
methods that match an interface, then the type implicitly implements the
interface.

~~~
aaronblohowiak
Oooooh, that makes sense. Thanks for the clarification.

------
BarkMore
Although the library coverage for Go is growing, it's tiny compared to what's
available in Python. Otherwise, I much prefer Go to Python for many of the
reasons given by the author.

~~~
stcredzero
I've been toying with the idea of doing massive rewrites of Python libraries
to Go using syntax directed translation. Getting to somewhere like 98%
fidelity is a very practical goal (I've done it and been paid for it!) and
gives a tremendous boost to programmer productivity.

------
budwin
"- It is compiled into machine code (no interpreter, unlike Python)."

anyone have any kind of measure on how bytecode compares to machine code these
days? (most "interpreted" languages have a hidden compile step these days). I
understand that this question is largely subjective to the runtime and the
task being executed.

~~~
kjksf
Compare on what basis?

Speed? <http://shootout.alioth.debian.org/> is an up-to-date, super detailed
answer to that question. A rule of thumb simplification I go by is: current
Python and Ruby implementations are at least 10x slower than C doing
algorithmic work.

A really good bytecode VM can, of course, get much closer to C performance (as
shown by Java, C# or even modern JavaScript implementations) especially if JIT
is given enough time to profile the app at runtime and generate highly
optimized code based on that profile data.

There are of course other aspect you can compare. Bytecode is, inherently,
cross-platform and machine code isn't.

Bytecode is usually more compact than equivalent machine code (but then you
need the constant overhead of the runtime to interpret that bytecode).

~~~
cdavid
Python is my main language, and I think you underestimate the speed different
_for a same implementation_ by an order of magnitude. That is, CPU-boud tasks
will most likely be around 100x slower.

The realy argument, of course, is that in a given time frame, with people of
similar skills, you will not have the same implementation unless your team
contains only vulcans. Several people in the scipy community have reported
having gone from C++ to numpy/scipy and went faster at the same time - because
C++ is so hard to use correctly, people whose job is not even programming
ended up doing things very fast but one millions times because they don't
understand their code.

This point is surprisingly not understood by a majority of programmers. Most
of the time, you see benchmarks for some trivial or even non trivial
algorithms, well specified, and get "look, this language is N times faster".
But in my experience, this almost never happens in real life - code
specification keeps changing, you need to redesign constantly what you're
doing.

------
xiongchiamiov
Several of the things he cites are a matter of preference (and using the right
tool for the job) - namely dynamic vs. statically typed, compiled vs.
interpreted.

> The documentation is very good and can be consulted instantly form the
> command line or from a browser, indifferently.

I can't speak for Go, but I've always found Python's documentation to be
fantastic. And very few things make me as happy as docstrings.

------
Kilimanjaro
I got rid of the shackles of curly braces, and once tasted freedom, it will be
damn hard to put me back in chains.

Over my dead body!

~~~
kjksf
It's very poetic sentiment but doesn't really address the issue of trade-offs.

Is writing if a { .. } else {} so much worse than if a then .. else .. end
(Ruby requires then/end instead of {}.

Python's indentation based syntax (which I think is great) cleverly solves the
problem of requiring explicit statement delimiters but it's also a reason why
lambda: is limited to one-liners. There's no free lunch.

To Go's credit they did put a lot of effort and design thought into removing
line noise from syntax (compared to C) by e.g. adding an automatic semi-colon
insertion rule, eliminating braces around if argument etc.

Overall, while syntax is not as clean as Python's, it comes pretty damn close.

~~~
andralex
I'm not so sure about giving credit. Consider:

    
    
      package main
      import "fmt"
      func blah() bool {
         return false
      }
      func main() {
        x := 5
        if(blah()) {
          x++;
        }
        fmt.Printf("%d\n", x)
      }
    

(which prints 5) and then this:

    
    
      package main
      import "fmt"
      func blah() bool {
         return false
      }
      func main() {
        x := 5
        if(blah())
        {
          x++;
        }
        fmt.Printf("%d\n", x)
      }
    

(which prints 6). Looks like a major problem to me, and at any rate it's a far
cry from having made real (or any) progress. Python _did_ get whitespace
right.

~~~
stcredzero
Python's approach has always been highly pragmatic. Go's is as well, but with
somewhat different goals. The Go team's goal seems to involve putting together
a clean-enough syntax with fast-enough for systems programming performance
combined with powerful-enough high-level concurrency model. They don't want to
win the gold in any one category. They're going for the decathalon!

In any case, language syntax should always take into account the expectation
of programmer communities. If you push syntax too far, you lose too many
people.

~~~
andralex
The point of my example was simple - Go's gross mishandling of whitespace is a
permanent trap for the unwary and a huge liability for people coming from
other languages.

When D was nascent, many people proposed various schemes for making semicolons
optional. I think it's great D didn't fall for such.

~~~
kjksf
I don't really follow what in your example shows "gross mishandling of
whitespace".

The most popular languages are C, C++, Java and C# and Go's syntax is very
similar to those. If anything, Python is the weird one in how it treats the
whitespace and hence most likely to confuse people coming from other
languages.

As to optional semicolon elision - what is the problem with that? They make
the code cleaner looking and gofmt will remove them for you even if you forget
due to C/Java reflexes. I don't see the downside of making them optional.

~~~
WalterBright
The problem is that the code looks correct for anyone coming from C, C++,
Java, D, Javascript, etc., but produces unexpected results.

~~~
jibal
It's an interesting way to enforce K&R indentation style.

~~~
andralex
That statement takes considerable license with the word "interesting" and
practically reverses the meaning of "enforce".

