top | item 4217890

Having a Go - first time experience with Golang

53 points| _ompc | 13 years ago |robotmay.com | reply

54 comments

order
[+] jgrahamc|13 years ago|reply
When you write:

  cli_host := os.Getenv("STOMP_HOST")
  if cli_host != "" {
    client.Host = cli_host
  }
you would be more idiomatic if you use a ; like this:

  if cli_host := os.Getenv("STOMP_HOST"); cli_host != "" {
    client.Host = cli_host
  }
But given how repetitive your setOpts is I think I might have rewritten it something like this:

  func getEnv(e string, d string) (r string) {
    if r = os.Getenv(e); r == "" {
      r = d
    } 

    return
  }

  func (client *Client) setOpts() {
    client.Host = getEnv("STOMP_HOST", "localhost")
    client.Port = getEnv("STOMP_PORT", "62613")
    client.User = getEnv("STOMP_USER", "")
    client.Password = getEnv("STOMP_PASSWORD", "")
    client.Uuid = getEnv("STOMP_UUID", stompngo.Uuid())
  }
But then I have a thing about duplication.

Have fun with Go!

[+] robotmay|13 years ago|reply
Ah ha, I'd seen that style being used in a couple of libraries but I wasn't sure which was the more accepted standard. I'll make sure I use that format in the future.

Update for your update:

Aye, I wouldn't normally write so repetitively but I wasn't too sure about the best practice for things like that and I decided to just hash it out so I could play with the data. Thanks for the tips; I'm really keen to improve quickly with Go, as it's very enjoyable.

[+] james4k|13 years ago|reply
I've always had a bit of an issue with these if statements. It might be slightly more concise, but your code also isn't as straightforward to read. In fact, it's really only more concise in its use of vertical space, so for clarity's sake I'm not sure I see the point.
[+] thebluesky|13 years ago|reply
I was planning to use Go on a new project, but there were two blockers that made me decide against using it: the 32bit memleak issue and lack of support for older Linux distros.

The go guys seem very dismissive of valid concerns from developers who really want to use Go:

e.g. Sarcasm for users who need to run on older linux kernels and distros: http://code.google.com/p/go/issues/detail?id=3211#c14

e.g. Solutions for 32bit memory leak is: works for me on 64bit: http://www.youtube.com/watch?v=kKQLhGZVN4A

I bought a book on Go and was planning to use it for a new project, but decided against it after seeing the disregard for developers with valid concerns who want to use the language.

[+] enneff|13 years ago|reply
I don't think the examples you've provided here are indicative of a generally dismissive attitude. There's more nuance than you realize.

> Sarcasm for users who need to run on older linux kernels and distros

The person Russ is sarcastically replying to is someone we know; a contributor to the project. I can see how it might look a bit blunt from the outside.

Perhaps more illuminating is Russ' later comment on the issue: "Old operating systems will always be with us. The fact that in 2020 people will be running a Linux distribution that forked the kernel 13 years earlier does not mean we have to support it." Which I feel is entirely reasonable.

> Solutions for 32bit memory leak is: works for me on 64bit

We've acknowledged the issue and work is in progress to fix it. In the meantime, however, "It works on 64-bit" is a legitimate response because it's true, and there is nothing you could do to help the programs that were affected on 32-bit systems. We never closed the issue was "works for me," we just said that's a reasonable workaround for some people.

The Go developers and wider community care a great deal about our users. We have some of the fastest bug fix turnaround of any project I've seen. We do, however, have our goals and priorities and sometimes people don't agree with them. There's not a lot you can do about that.

[+] srik|13 years ago|reply
1. The 32 bit memleak is indeed a prioirity and the Go team has made definitive statements about dealing within coming couple weeks.

2. Most of the team is a bit young and cheeky but they do mean business and actually engage the public very patiently about modifications/improvements etc in their mailing list. The dismissive attitude is usually them trying to stick to their core goals of making go an expressive, orthognal and highly readable language. Usually they have good enough reasons for picking a choice.

I would seriously recommend you to "not browse through" some source code but rather "play" with it. It really does feel different. Its like the feel of a quick dynamic language but on a more type safe static language. Its kindof fun at the least. Not the mention their CSR inspired concurrency approach. Its really interesting. Give it a shot, what you got to lose?

[+] genwin|13 years ago|reply
Do you know if the memory leak still exists on 64-bit? I wasn't able to determine that. I've read that the solution is to use 64-bit, but I don't know if that really just means that a 64-bit system will take the memory leak far longer to crash it.

I'm not too concerned about the attitude of some Golang devs (they are volunteers, after all), but I am very concerned about any memory leak or other serious bug that won't be fixed for a year+.

[+] genwin|13 years ago|reply
The way I see it, Go outshines all other languages all things considered, at least for my use case. The combination of general speed (with quick compilation), goroutines (to relatively simply keep all processor cores working, for even greater speed), and high-level language features & look & feel (e.g. garbage collection) seems unbeaten. And what a comprehensive standard library for a version 1 (blows me away!). All subjective opinion of course!
[+] cletus|13 years ago|reply
I've recently decided to pick up Go myself for a little experiment I'm running. I highly recommend the free "Learning Go" ebook [1] [2]. It's barely over 100 pages (huge plus).

There are some things that annoy me.

1. Reversing type and variable/parameter name is just aesthetics I guess but it still really bothers me. Perhaps there's a reason (eg parsing speed) but I'd still prefer:

    float32 f1
    float32 f2 = 45.4
over

    var f1 float32
    var f2 float32 = 45.4
2. The language is in UTF-8 so you can have snowman variable names but weirdly what gets exported from a struct or package and what doesn't is decided by uppercase/lowercase (respectively). This is a very Euro-centric concept.

3. The use of braces in struct/array/slice initializers is also a little weird.

4. Probably the biggest lacking area--and I realize this is a deliberate choice--is the lack of some form of generics. I realize there are good reasons for this. If you look at Java or C#'s generics you'll see that static type checking with generics can result in some thorny edge cases.

Still, using interface{} is rather awkward and limiting and there aren't (truly) universal map, filter or reduce functions like you have in Python, Ruby, etc.

5. Still immature IDE/debugger support. I tried to set up the Go plugin on IntelliJ (my preferred IDE) but in creating a project it would fail throwing NPEs in the logs for reasons not quite clear to me.

In the end I'm using Sublime Text 2 + gocode + MarGo (for syntax completion) and it's quite nice but Sublime has some things that annoy me too (eg no "delete line" out of the box; need to add a macro). Also if you're scrolling through an auto-complete list and scroll too far up or down the list goes away and you're scrolling through the file.

That all being said, the things I like are a far longer list.

1. defer for cleanup over finally blocks (far cleaner IMHO). Minor nitpick: you do this:

    f := File.Open(...)
    defer f.Close()
Personally I'd prefer:

    defer f.Close
which is how you'd refer to functions in Python or Javascript rather than their return value, but again I guess this is a deliberate choice.

2. Anonymous functions;

3. No inheritance/overloading. This may be controversial but I consider it a plus. structs can still have methods;

4. Returning multiple values. Python tuples are probably a more general (and better?) solution for this but it is nice;

5. Named return variables. Much like defer, this has the potential to really cleanup error condition/returns in functions;

6. The concurrency stuff (channels/goroutines/etc) looks nice but I'm still a novice so I'll reserve judgement.

7. Unused variables and import statements are a compiler error;

8. gofmt official style, which will hopefully kill off style dialects.

Anyway that's my experience so far (a few days in).

EDIT: I forgot my biggest beef with Go by far: the name. Seriously, try searching for "Go". Even "learning go" or "go tutorial" will bring results mixed with Go, the Japanese game. "golang" helps somewhat.

Compare this with "Clojure", which is a fantastic name in that is means something and is unambiguous in search terms.

Note to anyone naming stuff out there:

1. Don't choose any name shorter than 4 characters;

2. If it's an English word (or a word in any language), misspell it in some way.

[1]: http://miek.nl/files/go/

[2]: https://github.com/miekg/gobook

[+] Peaker|13 years ago|reply
The edge cases regarding generics have to do with the mixing of inheritance subtyping and generics. The ML family have working generics and they work well. Go made the good decision of avoiding sub-typing, so they should not have a serious problem with generics.

The C# author, Anders Hejlsberg, back when C# was around 5 years old has admitted that they failed to study the state of the art of programming language design and repeating the (very old) nullability mistake. This should despell the myth that design mistakes in modern programming languages are intentional trade-off positions. It isn't true -- modern language designers simply forsake the process of learning the various state-of-the-art languages and decide to reinvent the wheel, poorly.

People get attached to languages, so this will hurt some feelings here, but I think this is true of Go too. Rob Pike and others have repeated the mistake of failing to learn from the state of the art and re-encoded several age old PL design mistakes that could have easily been averted. A couple of clear mistakes in Go:

* Everything is nullable

* Boolean blindness

Some features that Go should have stolen:

* Sum types and pattern-matching (this would help with boolean blindness)

* Type-classes (So much more powerful than interface inheritance, and can be implemented more efficiently in many cases)

Given the majority of programmers themselves also do not study the state of the art, these designs, for all their (avoidable) mistakes become popular and persist, and make us all live with poorer-quality software for much longer.

[1] http://channel9.msdn.com/Shows/Going+Deep/Anders-Hejlsberg-Q... (1:00:35)

[+] lucian1900|13 years ago|reply
About 1., it mirrors the syntax for goroutines "go foo()". Both are supposed to be modified calls and can take arguments, so passing a function would be semantically wrong.
[+] jesstaa|13 years ago|reply
1. Reversing type and variable/parameter name is just aesthetics I guess but it still really bothers me. Perhaps there's a reason.

The reason is that it is much easier to read for more complex types. eg. function pointer in C: int (*pt2Function)(float, char, char);

function pointer in Go: var pt2Function func(float32,byte,byte) int

Try writing a type that is a pointer to a function that returns a function in C. It's a bit mind bending.

[+] masklinn|13 years ago|reply
> which is how you'd refer to functions in Python or Javascript rather than their return value

It's what you'd do in pretty much every language other than Go, really. And it's quite annoying when defining the function inline: you have to remember the extraneous parens to call the function in-place.

> Python tuples are probably a more general (and better?)

Python's tuples are indeed more general, "better" is a more complex issue as the language does not provide much support for tuples management.

Erlang's tuple support is significantly better than Go's MRV-specific syntax in my opinion, so is Haskell's (although in Haskell you often would use dedicated data types where Go would use tuples, as you can pattern-match — and unpack — pretty much anything and declaring a datatype is extremely easy)

[+] nickpresta|13 years ago|reply
"1. Reversing type and variable/parameter name is just aesthetics I guess but it still really bothers me. Perhaps there's a reason (eg parsing speed) but I'd still prefer: float32 f1 float32 f2 = 45.4 over var f1 float32 var f2 float32 = 45.4"

I've always found this a nice change.

The first way, you read it as: I have a float variable, named f1 and its value is 45.4.

The second way, you read it as: I have a variable named f1, it's a float, and its value is 45.4.

The second seems more natural to me, putting emphasis on your name and value, instead of the type. It is even more obvious when you use the := syntax. `f1 := 45.4` => "I have a variable named f1, whose value is 45.4 (a float)."

[+] kibwen|13 years ago|reply
2. The language is in UTF-8 so you can have snowman variable names but weirdly what gets exported from a struct or package and what doesn't is decided by uppercase/lowercase (respectively).

I knew that Go was both case-significant and Unicode-aware, but I had assumed (perhaps incorrectly) that they'd have some mechanism to export identifiers written in scripts that don't have a case distinction. Can anyone verify this? Or do they really expect e.g. Japanese programmers to write identifiers like `A緑` instead of `緑`?

[+] pcwalton|13 years ago|reply
What are the thorny edge cases that C# generics have? Java generics have use-site, not def-site variance, which is the source of most of the confusion... but C# gets this right.
[+] jussij|13 years ago|reply
> 5. Still immature IDE/debugger support. I tried to set up the Go plugin on IntelliJ (my preferred IDE) but in creating a project it would fail throwing NPEs in the logs for reasons not quite clear to me.

On the Windows platform the Zeus IDE Go language support has been constantly improving:

http://www.zeusedit.com/go.html

Jussi Jumppanen

Author: Zeus Editor

[+] robotmay|13 years ago|reply
I've had that ebook for a while but hadn't read it yet; I'll put some time into it this week I think.

Just on the editor front; I've had quite a pleasant time writing Go in vim, but I guess that depends on whether you would class using vim a pleasant time :D

[+] quarterto|13 years ago|reply
Slightly OT, but in Sublime Text, cut with no selection cuts the entire line.
[+] drivebyacct2|13 years ago|reply
The sooner you stop trying to use Go with an IDE, the happier you will be. Seriously, I promise. Go+Sublime. It gets you syntax highliting, auto completion, import fixes (soon via Margo), automatic go fmt, builds started from inside Sublime if you want.

A graphical debugger is about the only feature you get in an IDE (at least that I use often in projects that I'd use Go for) that's missing and I'm happy enough with other debugging tools.