top | item 5441757

Introduction to Go 1.1

255 points| sferik | 13 years ago |go.googlecode.com | reply

237 comments

order
[+] acqq|13 years ago|reply
Two most interesting news for me are:

> The garbage collector is also more precise, which costs a small amount of CPU time but can reduce the size of the heap significantly, especially on 32-bit architectures.

Previously, 32-bit version was almost unusable is some cases when garbage collector kept the allocations for which he falsely believed to be used even if they were not. I'd like to know if this means that the problem is finally solved.

> Previous Go implementations made int and uint 32 bits on all systems. Both the gc and gccgo implementations now make int and uint 64 bits on 64-bit platforms such as AMD64/x86-64.

This is a C-like can of worms, forcing you to test on more platforms just to be sure that you have portable code. I believed there's no reason to do such things with primitive data types in the new languages of 21st century (compare with http://docs.oracle.com/javase/tutorial/java/nutsandbolts/dat...). I'd like to see any discussion about such in my opinion quite strange decision.

[+] dsymonds|13 years ago|reply
Re: size of int and uint.

The size of these types have always been specified to be either 32 or 64 bits. The only change here is that 64-bit platforms will actually use that flexibility.

The probably most important consequence is that now you can have very large slices. The length of a slice is defined as fitting in an int, so slices were restricted to 2B items (signed 32-bit max); now they can be much larger.

I don't think there's any new gotcha here with having to test on multiple platforms. This is a change intended to give much more flexibility, but that flexibility naturally has to come with possible platform variation. If you are highly concerned with portability, avoid the int/uint types, and use the sized types (int32, int64, etc.) as much as you can. But in real code, as it turns out, it is rarely a big deal.

[+] pifflesnort|13 years ago|reply
> This is a C-like can of worms, forcing you to test on more platforms just to be sure that you have portable code.

Hardly. If you need fixed integer widths, use the fixed integer width types. If you need types that are 'optimal' for the target architecture, use the non-fixed-width types.

The only time you run into trouble is when you make silly assumptions about the width of non-fixed width types, which is a bad idea in almost any language that doesn't vend automatic "bignum" scaling integers. It's not as if you can ignore the width of the types in Java.

Apple does the same thing themselves with ObjC; NSUInteger/NSInteger are uint32 on 32-bit systems, uint64 on 64-bit systems. All in-memory lengths, counts, sizes, etc (but not offsets) are defined as NS(U)Integer values.

I've done the same in my own code that's portable from 8-bit to 64-bit CPUs. Works out just fine.

Java is itself an odd duck; using fixed-width signed types without also offering unsigned variants has been a plague on every single person who has ever had to parse binary data in Java, ever.

[+] georgemcbay|13 years ago|reply
Making int 32-bit or 64-bit depending upon the bitness of the current arch is one of the few Go language decisions I disagree with, primarily because it causes confusion with CGo since int in C/C++ (while technically compiler-specific) is, in practice, always 32-bits even on 64-bit platforms.

People writing CGo code can avoid this easy enough by understanding the issue and using C.int where they want C style ints, but I've run into more than a handful of examples of actual code in the wild using CGo that has issues because it expected 'int' in Go to be the same size as 'int' in C, which it will be if the arch is 32-bit, but won't be if the arch is 64-bit. eg:

https://github.com/visualfc/go-ui/issues/11

IMO the right call would be just go with what C does and treat both int and int32 as 32-bit ints, int64 exists if you need it, but having 'int' size be different between C/C++ and Go on the same arch violates principal of least surprise, IMO.

[+] fulafel|13 years ago|reply
On the go-nuts list people have been reporting large slowdowns with the new precise GC, and someone even backported the old GC to Go 1.1.
[+] jgrahamc|13 years ago|reply
Worth also knowing that the Go team has made significant improvements in crypto speed:

https://code.google.com/p/go/source/detail?r=eb2c99e6ec17db2...

https://code.google.com/p/go/source/detail?r=e7304334527349c...

https://code.google.com/p/go/source/detail?r=e5620fd3ba5fb1d...

Fast approaching OpenSSL speeds.

Also, the integration of the network poller into the main scheduler is likely to make a big difference to Go programs that make heavy use of the network.

[+] mseepgood|13 years ago|reply
It's not released yet, this is just a preliminary document. There are still open issues for Go 1.1: http://swtch.com/~rsc/go11.html And I guess there will be a RC first.
[+] laumars|13 years ago|reply
Is there any ETA on the release or is it just a case of "when it's finished"?

I'm about to start a largish project in Go and I'm thinking I'd rather start in Go 1.1 rather than worry about upgrading and testing the project mid-development.

[+] melvinmt|13 years ago|reply
For those of us who are wondering if 1.1 is stable enough to upgrade: Google is already using Go 1.1 in production.

And the company is betting big time on Go, more than 50% of their codebase will be (re)written in Go in a couple of years.

Source: core dev on the golang team.

[+] bradfitz|13 years ago|reply
I am a core dev on the golang team.

Teams and engineers at Google can use whichever language they want. (trade-offs abound) We're trying to make Go be the most compelling language with the fewer trade-offs so they're willing to switch. It's getting increasingly popular.

It's possible that 50% of new code will be written in Go in a couple years, but I've never seen that written as a goal. (And we do have goals. And usage charts over time, for each language, inside and outside the company, etc.) There's no way we'll rewrite 50% of all code in a couple years... there's so much code.

[+] BarkMore|13 years ago|reply
I doubt that Google is rewriting 50% of their code in two years. Perhaps they said that 50% of new projects will be written in Go.
[+] etfb|13 years ago|reply
I grew up with Pascal and its derivatives, so I have a strong sense of the aesthetic of programming languages. I can't take Go seriously, or bring myself to use it, because it appears to have no aesthetic sense at all. It's ugly! Strings of keywords and punctuation, no rhythm to it, just a lot of mess. Like a cross between C and Prolog, perhaps, with a smattering of Python but only the ugly bits. I really don't like it.

Now, if you want to see a recent language with a bit of style to it -- and bear in mind I know nothing of how it is to use in practice, so I'm basing my opinions entirely on the look of it -- I think Rust is one of the best of the pack. So much smoother.

TL;DR (for any Redditors who may have stumbled in on their way to the Ron Paul fansite): languages have a flavour, and Go's flavour is "mess".

[+] stefantalpalaru|13 years ago|reply
> I can't take Go seriously, or bring myself to use it

But you can criticize its aesthetic nevertheless? Maybe if you could bring yourself to use it you might appreciate the elegance of the Communicating Sequential Processes implementation. Or maybe the clean OOP practices derived from using interfaces. Or the beauty of coroutines mapped unto multiple OS threads.

tl;dr: learn it properly before complaining it's not like mom's cooking

[+] otikik|13 years ago|reply
I believe that the beauty of a tool relies purely on its usefulness. Your comment sounds to me like someone saying that Michellangelo's David is "ugly" because the sound it makes when hit by a hammer is not armonious.
[+] lobster_johnson|13 years ago|reply
Sure, Go is ugly. I had the same reaction as you. But it's so damn functional. There are plenty of warts, syntax and design-wise, but once you get over them, it's actually a decent language.

Compared to Erlang, for example, it's positively beautiful. I like Erlang's execution model, but the unnecessarily gnarly syntax and the antique approaches to some things (no real strings, no Unicode, tuples that depend on positional values instead of named attributes, horrible stack traces, tail-call recursion as a looping construct, etc.) has made me stay away.

Go is a decent alternative to both C/C++ and Ruby for me these days. There are plenty of things I don't like about Go, but it's easy to forgive many of them when the language makes you so productive (at least for the things I need it for; it's pretty bad at web app development and completely useless for GUI development), so I do. Sometimes you just want something that works, with minimal amounts of pain. C++ works, but is always painful to me because it feels like the language is working against me, not with me.

I love the simple syntax in Go; the no-nonsense approach to object-orientation, the way the typing system allows adding methods to arbitrary types, which may have been inspired by Haskell's typeclasses. I love having native Unicode strings, first-class functions, a simple package system, built-in concurrency and decent networking in the standard libs. I love the built-in documentation generator (although it's too simplistic at this point; why not Markdown?).

Things I don't like:

* Capitalized names for visibility.

* nils in the language instead of Haskell-style Maybe.

* nil cannot be used in place of false.

* The "non-nil being nil" insanity (an interface value can be nil, but it can also be non-nil and contain a nil value).

* Functions return errors instead of Haskell-style Either monads, or Erlang-style matching. (I see the problem with exceptions, but Go's solution is worse and leads to very awkward code that has to branch a lot to catch errors.)

* The fact that "go" is a language keyword; compare with Rust's very elegant task spawning, which is part of the standard library rather than being built into the language, and yet relies on first-class language constructs to integrate perfectly.

* That "range" is not extensible (that I know; it only works on maps, arrays, slices and channels).

* The whole GOPATH thing, pretty much requiring that you maintain a local tree with symlinks.

* That "import" when used with Git cannot be pinned to a specific revision (so if you rely on a third-party package, it could break your app at any time if HEAD changes; it's ridiculous, and counter-productive, to have to fork third-party repos just because of this).

* That packages have only a single nesting level. I don't mean that I should be able to create a package "x.y.z", I mean that given a package "x", all the files have to be in the same folder. I can't organize the tree in multiple subfolders.

* That statements are not expressions.

* That semicolon elimination necessitates some insane syntax at places (like having to end a line with ",").

* The lack of structural tagging in the language (similar to Python and Java annotations), and the fact that they did add tagging, but only for struct fields, and the tags can only be strings.

Right now, Go is, in my opinion, mostly an inelegant, weirdly-shaped thing that fits into the weird hole not filled by C and C++, a stepping stone to the next big language. I don't love the language, but I love how I can do the same things I was planning to use C++ or Ruby for; as a C++ replacement I gain productivity and simplicity; as a Ruby replacement I gain performance.

Go is, if anything, a very pragmatic compromise that favours simplicity over complexity at the expense of structural and syntactical elegance. It looks a lot like Java around 1.3-1.4, before the enterprise stuff derailed its focus. My concern is that Go has no particular philosophy as a foundation; it bakes in some current concerns (concurrency, networking, ease of use) and made itself a very useful hammer for hammering today's nails, but may not be as easy to extend to work with tomorrow's screws.

PS. I, too, come from Pascal — specifically, Borland's Object Pascal. While I have fond memories of that language, I'm not sure elegance was one of its main traits.

[+] laumars|13 years ago|reply
When choosing a language for a job, I'm often concerned about whether the source code is apathetically pleasing. After all, execution speed, portability, compile time, development time, usable toolkits and maintainability are all irrelevant if the source code isn't pretty enough to frame and hang on your living room wall.

</sarcasm>

[+] im_dario|13 years ago|reply
As a polyglot developer, I found Go syntax just nice. It is not maybe so sweet as Ruby's syntax (which I like) but it just feels right.

Rust makes me think on Haskell but it is not so far away from Go, IMHO. I just skimmed Rust tutorial so I'm probably missing something.

[+] davidw|13 years ago|reply
I'm interested in tracking Go as a replacement for Erlang. Some things that should probably happen:

* GC works on 32 bit systems.

* Scheduler improvements so that things are a bit more robust ( http://code.google.com/p/go/issues/detail?id=543 )

* A fairly solid library implementing supervision trees or something like it.

* Probably some other things, but those strike me as the big ones. The important thing is for the system to be able to run for months at a time.

I think they'll get there eventually. Maybe not 100%, but 'good enough' sooner or later.

[+] GhotiFish|13 years ago|reply
Whenever I look through golangs specs, I always get stuck on the same question.

Why are the methods we define restricted to the types we define? I'm SURE there is a good reason.

Others have said that it's because if you did allow that kind of thing to happen, you might get naming collisions in packages. I don't buy this argument, you could get naming collisions anyway from packages, Go resolves those issues by aliasing. Go also allows for polymorphic behavior by packaging the actual type of the method caller with its actual value, so resolving which method to use isn't any more complicated.

I don't get it, I'm sure there's a good reason! I just hope it's a good enough reason to throw out the kind of freedom that would allow you.

[+] Jabbles|13 years ago|reply
You can't add methods to a type in a different package as you might break that package. By locking the method set of types when a package is compiled you provide some guarantee of what it does, and it doesn't need to get recompiled again! This is central to Go's ideals of compiling fast.

Besides, embedding a type is very easy http://golang.org/ref/spec#Struct_types

[+] pcwalton|13 years ago|reply
Because if you had package A that defined type T, package B that defined method Foo on T and, separately, package C that defined method Foo on T, then B and C could not be linked together.
[+] thepumpkin1979|13 years ago|reply
Still missing custom generic types and methods :(
[+] _ak|13 years ago|reply
Experience with Go in the last few years has shown that you don't really need them. If you think you do, then you're doing it wrong.

Also: http://research.swtch.com/generic

[+] phasevar|13 years ago|reply
Sweet performance improvements! Definitely looking forward to seeing Go 1.1 on the benchmark game.
[+] trailfox|13 years ago|reply
Definitely looking forward to seeing if Go has made any progress in catching up to Java and Scala in algorithm execution times.
[+] ubershmekel|13 years ago|reply
> In Go 1.1, an integer division by constant zero is not a legal program, so it is a compile-time error

How often do be people accidentally divide by a constant 0? I personally use that to simulate runtime errors all the time in python. It's shorter than writing "raise Exception()".

[+] jsmeaton|13 years ago|reply
I'm not familiar with Go, but I'd imagine something like this:

  const int SomeNumber = 0;
  // then much later in the program
  return 3 / SomeNumber;
An accidental and not immediately obvious divide by constant 0.
[+] laumars|13 years ago|reply

    > How often do be people accidentally divide by a constant 0?
As much as I do love the level of checking that Go's compiler does, I must admit I asked myself that same question when I read the article.
[+] dsymonds|13 years ago|reply
Go has a builtin function called panic, which is much more useful and well-defined. panic("simulated runtime error")
[+] IanCal|13 years ago|reply
> How often do be people accidentally divide by a constant 0?

Depends how far the compiler goes to simplify constant expressions. It could be quite useful if it detects something like:

f(x,y) : x / (x - (2*y))

f(6,3)

[+] enneff|13 years ago|reply
This change was added to ratify an assumption that the compiler had already made. As has been pointed out, this is not a big deal. Almost nobody is affected, but our release notes must be comprehensive.
[+] duaneb|13 years ago|reply
It's possibly easier to specifically handle that corner case.
[+] verytrivial|13 years ago|reply
What about programs that write programs that divide by zero?
[+] przemoc|13 years ago|reply
We have integer madness here and no one is commenting on it. Why making this int change and why now? I don't like Java, but well-defined integer types sizes is a good thing. Most of the world uses intXX_t typedefs in C and C++ too.
[+] laumars|13 years ago|reply
Nobody is commenting because there isn't any integer madness.

If the size of an integer is critical to the execution of your program, then you should be using int16 or one of the many other types that specify the number of (un)signed bits.

The int type is designed to be platform specific to optimize on execution speed when the maximum size of the integer isn't an issue.

http://golang.org/ref/spec#Numeric_types

[+] grey-area|13 years ago|reply
Go uses specific int types like uint32, int32 and int64 etc. so it does have well-defined integer types. It does also have a platform specific int type - like C or C++ the size of int can vary depending on the platform, so it's probably best avoided for any operation which cares about the size/precision.

In practice, as noted in the link, this is not a big deal as most people will use a specific type to avoid any potential issues, particularly when dealing with bitfields etc. you should be doing this anyway.

[+] vanderZwan|13 years ago|reply
Yeah, but C and C++ have implicit casting where Go doesn't, so this is not quite the same issue.

And quite frankly, if your code relies on a an integer to be 32 or 64 bits, you should be using int32 or int64.

[+] mseepgood|13 years ago|reply
Go has (u)int8, (u)int16, (u)int32, (u)int64 types if you must make assumptions about the size.
[+] zemo|13 years ago|reply
because it was consistently communicated that int is currently 32 bits wide but that it would be changing to be architecture-specific; this has been a planned change for a very long time. It has always been the case that if you needed width-specific behaviors, you specify int32 instead of int.
[+] mortdeus|13 years ago|reply
Can you please delete this article until go1.1 is officially released. Just in case the go developers make any last minute changes. Otherwise this article may lead to confusion for those who choose to skip out on reading it on golang.org when go1.1 is released because they read it here.
[+] joeshaw|13 years ago|reply
"We trust that many of our users' programs will also see improvements just by updating their Go installation and recompiling."

Does anyone know if it is possible to determine what version of Go a given binary was compiled with? Perhaps extracting some metadata from an ELF section?

[+] VeejayRampay|13 years ago|reply
I'd more than welcome any instructions and pointers on how to install Golang 1.1 on my computer which has 1.03 installed already. Either to replace my current version or maybe to install it aside 1.03 for testing. Thanks a lot.
[+] djhworld|13 years ago|reply
I'm excited for this release.

I'm not sure if I understand what "method values" are though

[+] karma_fountain|13 years ago|reply
Yes, I wondered about that. Is it just that the function

  func (w *Writer, int n) {
  }
is actually a method, like:

  func (w *Writer) Anon(int n) {
  }