Hacker News new | past | comments | ask | show | jobs | submit login
Go 1 Release Candidate 1 (groups.google.com)
84 points by jbarham on March 14, 2012 | hide | past | favorite | 70 comments



One thing I especially appreciate about Go that's a huge win over other statically compiled languages is how phenomenally fast the compiler is. E.g., I just re-built the current RC release on my 2.67 GHz i5, and the whole build, including the C bootstrap environment and 300k+ LOC in the standard library, took under 30 seconds.

Recompiling my projects of a couple of thousand lines is instantaneous. It really makes you re-think the classic edit-compile-edit cycle since the compile time is negligible.


I wonder why people are so impressed by the compile times. Why it is fast, is obvious:

1. Do not use #include (especially in combination with C++ template instantiation)

2. Do not use a heavily optimizing compiler backend

The first point is fixed in every other modern language as well, so it is only an advantage over C/C++. Go will become somewhat slower, because people want free lunch, so at some point i expect LLVM or GCC will be used as the official backend. Does anybody use TinyCC for his C programs?


You are mistaken about #2, optimization pass is not very relevant in total build time, even for compilers that spend a relatively long time in the optimization pass. Go build times are fast because 1) the grammar is not ambiguous to yacc yielding an O(n) parser that doesn't require maintaining a symbol table, 2) Dependency resolution is handled in an unique way, objects pull their dependencies so if A depends on B, C depends on A, and D depends on C and B, D doesn't need to look for B, since C contains A, B, and C. This doesn't seem like much, but it is, build times scale linearly with the number of objects instead of O(n^2).

The gc suite doesn't produce code as tight as gcc, but almost no code in the world is CPU bound, everything is I/O bound.


Could you link to a resource that describes Go's dependency resolution scheme? Specifically, I'm curious if this means that all libraries are dynamically linked, and if so, if this inhibits Go's ability to inline function calls between libraries.


Go libraries are statically linked and inlining works across libraries.


Dynamically linked libraries are actually a little problem in Go. Library is opened via dlopen()/LoadLibrary() and symbols needed are looked up by the Go code, not by system dynamic linker.


That's not true at all. In the few cases where dynamic linking is involved, it works just as you'd expect it to be.


Go does not use native dynamic linker.

Please check package syscall, specifically src/pkg/syscall/dll_windows.go. You will see for yourself, how it is implemented.


I find gcc usually spends about 80% of the total compile time in optimization with -00 as a baseline (which despite being 'no optimization' actually does some optimizations). This is just C code.

Optimization takes a massive proportion of compile time these days. This is something the Google Go designers didn't understand because they had been programming for decades using a mostly unoptimizing compiler (for plan 9).


You will find that even though GCC spends 80% in the optimizing stage (I won't bother to refute your claim), impact of this is negligible in the grand scheme of things. The build is slow is because it scales O(n^2) with the number of files, and because there are many more steps involved in building a product, not because the compiler is slow (although GCC is).

Go is designed to handle dependencies between objects in such a way so that it scales O(n).

The Solaris/OpenSolaris/illumos build builds with two compilers at the same time. The Sun/Oracle proprietary compiler that generates better code, and GCC. GCC generated binaries are not usually used, instead GCC is used a shadow compiler to catch potentially not portable statements.

You will find that if you disable GCC and build with only one compiler, build time decreases by 2%, not 50% as you might have expected.


Well it's true that the Go compiler isn't comparable to GCC in terms of optimization but it's still quite new and is likely to improve quite a bit. As for Go supporting other compiler backends that's already happening with GccGo which is a Go frontend for GCC and yes it does generate much faster code than the official compiler (although it still lacks some key features last time I checked).

I don't think we'll see GCC (or LLVM) as the official backend though, as they've stated that the reason they decided to do the whole compiler from scratch was that both gcc and llvm backends were considered too large and slow.


> although [gccgo] lacks some key features last time I checked

Not anymore. Gccgo is "Go 1 complete" and will be supported as part of Go 1. You can even use the "go" tool with gccgo.


Thanks for the info, that's very nice. I can see this opening up a workflow where you develop against the standard compiler and then use GccGo for better performing final builds.


This is just marketing.

Any language with modules is equally fast, only languages the use the C #includes mechanism are slow, because each #include needs to be imported and processed each time it is seen.

Turbo Pascal, Modula and Ada compilers were already running circles around C compilers back in the day.


It's absurd to claim it's marketing since in this exact thread people state they care about this things and appreciate the feature, a feature that can be quantitatively tested.

Btw, The Plan 9 C compilers, which are also included with the Go distribution, also compile C as fast as the Go compiler compiles Go. Both compilers were written by Ken Thompson.


It is marketing, because it is sold as Go was the first language to have such fast implementations, which is not the case, but many refer to Go as if it was the first language having such a feature.


Nobody ever claimed Go was the first language with a fast compiler, it was simply claimed that it builds much faster than C++ and Java.

There are compilers faster than the Go compilers in terms of lines compiled per second. Even Python parses code faster than the Go compiler, however, Go builds large, real life projects, faster because it is the only implementation that scales linearly with the number of components, other scale O(n^2)

Turbo Pascal, Modula, and Ada, which you bring into discussion may have had fast compilers, but the build process was still O(n^2), not O(n).


Numbers please


A fast compile time is one of the stated goals, is it not? I ask because this seems like the kind of thing that's hard to do correctly unless it's explicitly stated as a design goal.


Yes, the projects at Google in C++ or Java took an absurd amount of time to compile, even with distributed compiler farms.


>how phenomenally fast the compiler is

This, more than anything else, is what's really got me interested in trying out Go when I have some time! I know it's not the most important thing in the world - my projects are generally such that compile times aren't a huge time suck - but it's still an exciting thought nevertheless.


The language is pretty much amazing. There is so much that is right with it. The tools are very helpful. The makefile free build tool it ships with, 'go', is great. Things are really well documented. The source code is easy to read. I have been working on making a control panel with Go for our APIs. It has been pretty straight forward and painless to pick up on go.


Actually, the 'go' tool is one of the things I rather dislike in Go so far. It's good to have to tool that does everything for you, but I'd like to at least be able to structure my directories in the way I want. For mixed-language projects you won't get rid of Makefiles either way, and they're really not that bad with the right include files or Makefile generation tools.

Using URLs to identify external libraries also isn't something I'm very fond of. Both because you'd have more boilerplate to type when using them, and suddenly the library is fixed to a certain internet location and VCS.

Meh, I can go on ranting about other things I dislike about Go, but it wouldn't solve anything. I'll just keep monitoring the developments from the sideline and see how things evolve over time.


The URLs are not really fixed, there's a feature which I am not sure if it's documented yet that allows for an indirection between a shorter import path and the real import path, so you could change the VCS or the real location.


According to various sources on the Interwebs, Go sucks for one or more of the following reasons:

- No generics.

- No exceptions.

- No inheritance.

- Nullable pointers.

- No decimal types (yet they put in complex!)

- No IDE.

- No support for GUI applications on Microsoft Windows.

- Go ignores years of academic research on language design.

Please ignore the people who are happily productive with the language :).


Some of your points are not really fair:

Go does have exceptions under a different name called "panic". It's named differently to communicate why they were added to the language (read docs for details) and their expected use-case.

Go does have a variation of inheritance called embedding. Using embedding you inherit all methods and fields of the former type but that does not provide is-subclass relation between types. In order to have abstract-class-like behavior one would use interfaces.

---

At the moment Go is mostly useful for creating lean network services. "net" package from standard library is really good. Goroutines are scheduled with the respect to system calls so all your code is effectively async without any jumps and hoops (no callbacks!).

There are few packages in other areas (gui) but that's not the fault of the language. You're welcome to write new ones or wrap existing C libraries (and that's really easy in Go).


> Some of your points are not really fair:

Go also has generics, they just are not available to lowly peons writing new Go types.


My point is that people are happy and productive using the language despite the list of complaints about missing features.

(I will avoid any attempt at humor in future posts on this site.)


+1


Funny, none of those reasons are why I now avoid go. For me what killed it was:

- Forcing one brace style - Forcing naming conventions to a certain extent - To use the Go tool you are required to have your directories set up in a specific way - All types are not equal: No support for using user defined types as map keys, maps are generic, but user defined types are not - Two initialization functions, new and make. One returns a pointer, the other a struct. Seeing as go makes no distinction between the stack and the heap, is there need for two.

Convention over configuration is great and all, but it really felt as if it was being used as an excuse to force me to use someone else's style. Even python which catches flak for forcing indentation as tabs let's you choose the indentation depth and character. Go made me feel slightly violated; forcing my directory layout was the last straw, and the lack of any configuration in a place where it would not be complex to add it seamed stupid.


You can't imagine how annoying is it in python world to use libraries which always provide inconsistent naming scheme. You'll easily find camelCase, snake_case, nocapitalorunderscorecase in any large project. Even though pep8 exists, neither standard library nor most of 3rd party developers conform to it.

Go's CapitalEverythingNaming convention is quite annoying but the mere fact that it'll be used everywhere makes me happy.


A few comments :

- I find that having a common style about source files from different origins (we're in the open source era) and common naming conventions are great for the readability. I can decipher foreign code much easier if I don't have to set my mind about the bracing style. And seriously, would you prefer to have "private" and "public" all in the place instead of this simple convention ?

- I found it a little painful too, at first, to have to mix source and binary in my projects with the advent of the go tool but the removal of redundant makefiles and its simplicity of use, especially when you deal with a lot of projects and packages from diverse origins is so great that it's hard to protest against that.

- Are you sure you're up to date about map keys ? http://tip.golang.org/ref/spec#Map_types


Even python which catches flak for forcing indentation as tabs let's you choose the indentation depth and character.

You can use any indentation depth in Go too. But in Python you can't get rid of indentation because its lexer expects it, just like you can't get rid of the "forced" brace style in Go, because its lexer expects it.


>Forcing one brace style

This has been discussed numerous times on the mailing list. The answer, for good reasons, is too bad. As you note in your conclusion, consistency is prioritized above configuration.

There's reasons for this, they were meticulously debated and chose by the designers to help people out. If you have a pure Go project, you can install it anywhere Go is available in a single command. No autotools, no makefiles, no build-essentials, nothing. Just a single `go get` command.

If you ever work on a decent sized project in Go, you will quickly come to appreciate the enforced consistency across the project.

>To use the Go tool you are required to have your directories set up in a specific way

Not with the binary distribution. And "have a source directory on GoPath" is too restrictive... set `GOPATH=~` and for 90%+ of users, their existing dir structure is perfectly fine.

>No support for using user defined types as map keys

This is no longer true IIRC.

>Two initialization functions, new and make. One returns a pointer, the other a struct.

I don't understand why this is a negative?


I've been off Go for a while, weren't they thinking about getting rid of new at some point? I recall a long thread on the mailing list debating dropping it.


Most of the "debates" I've seen have been people desperately trying to explain that they do different things under the hood and thus removing the different keywords adds 'magic' that they don't want.


If those reasons matter to you, try D. http://dlang.org/


Or Rust.


I want to like Rust because it's mentioned everytime Go is, but the syntax is just so disgusting. I know that seems petty and is a personal opinion, but part of the joy of Go is that anyone can grok it immediately. I've had three projects now on GitHub that I've built for classmates. Several of them have told me that they were able to read the source very easily (after an explanation of `go` for goroutines). I don't find that to be the case with Rust, even for relatively small examples.

As for D, I simply need to give it another go, pardon the choice of words.


What in particular do you not like about the syntax of Rust? We're still designing the language and we are very much open to suggestions.


+1


Why do you do this? Isn't it enough to just upvote?



Wouldn't Go be a good fit for Android? That would be on my wish list.


releasing without generics is a huge mistake


I've written a fair bit of Go code, and rarely miss generics.

Two Go features in particular help to mitigate the lack of generics:

1. The built-in array/slice and map containers are effectively generic since they can act as containers for any type.

2. Interfaces (http://weekly.golang.org/ref/spec#Interface_types) define a set of common methods that can be implemented by multiple concrete types. See e.g. the ubiquitous io.Reader interface (http://weekly.golang.org/pkg/io/#Reader), and the SQL database driver package (http://weekly.golang.org/pkg/database/sql/driver/) that defines a collection of interfaces that define an interface to any SQL database. FWIW I've written a concrete PostgreSQL driver: https://github.com/jbarham/gopgsqldriver.


Your argument is not clear to me. However allow me to share some of the Go authors' thoughts about generics:

http://research.swtch.com/generic

http://commandcenter.blogspot.com/2011/12/esmereldas-imagina...

I am inclined to agree with them. I like writing Go programs quickly, but not at the expense of compilation speed† or execution speed. The point of Go is to be fast. If I valued programming speed for a particular program, then I would use the right tool for the job and choose a language other than Go.

† Though considering the speed of Plan 9-style compilers, I can't imagine at what scale this would begin to be a problem.


As I stated below, Go's lack of generics isn't buying the language anything from an implementation standpoint. What Russ Cox is missing is that, absent some way to write generic code, programmers will end up paying the exact same taxes via their handwritten non-generic code.

Consider, for example, a binary search tree that can be instantiated with keys of int type or keys of string type. There are two ways to implement this in Go: (a) use an interface and dispatch calls through a vtable; or (b) implement the tree twice, once for ints and once for strings. But note: these two implementation strategies carry the exact same costs as the corresponding implementation strategies for generics! In the case of (a), the programmer is performing boxing via interface types, while in the case of (b), the programmer is performing code duplication. So not having generics doesn't relieve Go programs of compile-time or runtime overhead in any way; it simply increases the burden on the programmer.


Let's take case (a) -- that's the approach I adopted when implementing a Splay tree, introducing a Comparator interface. Granted it is a bit of a pain to write IntComparator, LongComparator, etc., but given that Go is not an object oriented language e.g. all types do not support a (hypothetical) CompareTo(other T), it is not clear to me how would the availability of generics would help in this case.

For basic type coercion, yes, it is a pita to write boxing code, and clearly a maintenance issue as well.


The simplest way that they would help your example is by ensuring that you can't add a mix of ints and strings to the same splay tree. Presumably this would cause a runtime failure. Generics add type safety.


> Go's lack of generics isn't buying the language anything from an implementation standpoint.

But it does buy us a lot from a code complexity standpoint. C++ templates and Java's generics have a horrific effect on readability and comprehensibility, two of Go's primary goals. Generics are hard. If/when we do them, we'll get them right.


I don't think Java's generics have a "horrific" effect on readability and comprehensibility, except for the fact that they have use-site variance instead of definition-site variance. (The ? existential type is kind of screwy too.) But neither of us are going to be convinced otherwise.


Horrific may be hyperbole, but I have seen many an incomprehensible parameterized Java type definition.


> However allow me to share some of the Go authors' thoughts about generics:

While forgetting Go has blessed in-runtime generic types because it turns out you really need generics.


Go also has blessed flow control mechanisms, because you need flow control.


There's a significant difference in that Go's "designers" have not been asserting there was no need for in their language.


On the contrary, it is vitally important.

Go 1 was a stabilization of what we already had, not an occasion to introduce new features.

If Go gets generics it will have a profound effect on the language and its libraries. better to introduce them in Go 2 once we know what they are and have a wealth of experience with them.


Does this make _any_ sense?

Normally you introduce stuff having "profund effect"s on the whole ecosystem _before_ you release something as "stable".

Maybe the Go devs want to repeat the Java generics story ...


Sure, we could have introduced generics (we have a pretty decent proposal in the works) and then tweaked it for another couple of years, but that wouldn't be fair to the thousands of Go programmers (including those at Google) who need to use Go in their day-to-day lives.

As has been mentioned elsewhere, part of the problem with Java's generics story was that they needed to maintain backward compatibility at all costs. The same won't be true for Go 2, which may include support for generics.

Go 1 is a solid product - language, standard library, and tools - and one we will support for years to come. There will be a time for experimenting with generics but that time isn't now. Why is everyone in such a rush?


Maybe. Certainly if releasing without them means they're going to be stuck with a half-assed Javaesque implementation later. On the other hand, generics can complicate a language implementation considerably.


From an implementation perspective, generics aren't that bad. For an ahead-of-time-compiled language, you either need a uniform value representation (like ML/Java) or a monomorphization pass (like C++). The former corresponds to what Go has today if you simulate generics with interfaces. The latter corresponds to what Go has today if you simulate generics by duplicating your code (for example, if you wrote an IntTree to operate on ints, a StringTree to operate on strings, and so on).

They do complicate the typechecker a little bit, largely due to the interaction with subtyping (which Go has via interfaces, I believe). You probably want definition-site variance, not use-site variance like Java, to keep things simple. Also remember that parameterized types must be invariant, not covariant, in the presence of mutability. (Additionally, if you have subtyping for function types, remember that the arguments are contravariant -- Go probably doesn't care about this, though.)

None of this stuff is that complicated, though -- it's all pretty straightforward at this point. There's no reason to fear generics.

Moreover, as noted above, all of the workarounds end up duplicating effort that the compiler could have done for you. If you use interfaces, you pay the tax of boxing. If you use code duplication, you pay the cost of increased compile times and increased binary size. Nothing is gained from not having generics, except maybe a simpler type system.


Java's top priority is to never, ever break anything. It has to be both binary and source compatible. That's a major reason why generics in Java are so broken. They couldn't change syntax to make it nicer and they couldn't substantially change jvm to make it generic-friendly. Which leads us to type erasure and weak integration of generics into the language.

Go has quite a different opinion on this question -- we'd rather break things but make a tool (gofix) to automatically fix all your source code. Also Go doesn't aim at binary compatibility at the moment as compilation time is _extremely_ fast and there are no shared library support yet.

Most likely they'll be more conservative with Go becoming stable and getting 1.0 release but that doesn't prevent them to break things for 2.0 if that's needed.


Note that, at the moment it looks like Go will never have shared library support. It seems to not be required and I think there's a conflict of interest with the complexity of (or lack of developer resources for) the fast linker Go uses.


We already have Java.


And that is relevant because?

Generics aren't a unique trait of Java --quite the opposite: the language existed for a decade without them, and even now doesn't have a nice implementation of them.


> And that is relevant because?

The goal of C-like languages isn't to duplicate Java features. Go (and others) have their own set of goals. In this case generics doesn't advance the goals.


Actually, the goals doesn't have anything to do with the presence of generic in the language or not.

Plus, the creators of Go have stated that Generics are indeed considered strongly as an addition to the language post 1.0.


If this thread proves anything, it's that independent research is needed when picking a language. There are many inaccuracies, anecdotes and personal opinions that in my and many others' opinions don't matter once you've actually built something useful in Go.


"There are many inaccuracies, anecdotes and personal opinions that in my and many others' opinions don't matter..." The content of your comment renders your comment meaningless. It's like a Hofstadter Strange Loop of meaninglessness.


I anticipated this comment, though I decided against discussing it. The core concept is clearly: "It's that independent research is needed when picking a language." and my anecdote merely served to counter the negativity and reiterate the importance of evaluating language choice based on one's needs.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: