Live data from Hacker News

A year with Go

vagabond.github.io

21–30 of 235 posts

Re: A year with Go

#21
post #4

When I use Rust I am constantly annoyed by how limiting traits are in comparison to interfaces. I much prefer interfaces, which are a single type, as opposed to traits, which are sets of types.

I don't see how traits are limited. Traits are types, though you need to put them behind a pointer (Box or &Trait) if you want to use them as types; and this is dynamic dispatch. You can use them in static dispatch (generics) too, and in general you should try to do that whenever possible. Plus there are loads of things you can do with them that Go can't (static trait methods, associated items, generics, etc) The onl…

[deleted]

Re: A year with Go

#22
post #10
post #2

The point isn't about learning something new. It's about trying to apply those things into a language they think is easier to work with.

I'd argue the point is the opposite of learning new things. As the Go team themselves say, Go is an engineering project. It's about sticking to well understood, well defined ideas that allow large teams of typical skill to develop and maintain good software. Go is boring compared to some other languages that push the envelope and try new things. But that can be a good thing if you start thinking like the business own…

Most people won't see it this way, but not pushing the envelope is a new thing.

Re: A year with Go

#23
> I also, apparently, don’t understand Go’s pointers (C pointers I understand fine). I’ve literally had cases where just dropping a * in front of something has made it magically work (but it compiled without one). Why the heck is Go making me care about pointers at all if it is a GC’d language?

Well, sorry, but if that's your level of understanding after one year of Go, I'm furious I wasted time to read your article up to that point.

Re: A year with Go

#24
post #16

[deleted]

I totally agree (except for the new-grad conspiracy.) I use Go whenever I need to do something small that requires a simple server or API interaction. Especially if it requires alot of concurrency. It's still a joy to use when I need to get something churned out quickly. The biggest thing it gave me though, was something new but accessible that wasn't Ruby, Python or JS.

It made me think about pointers, and gave me insight to just how complicated strings and growable arrays are under the hood instead of just being givens like in Ruby. It simplified concurrency and parallelization enough that I was able to dive in and learn the concepts which I was then able to use to dig deeper with other languages that don't have the nice channels/select built in.

I've come to realize that, in my learning at least, there are thresholds of information that people get stuck at, but once they cross you get a flood of improvement. Go allowed me to stop thinking only within the code context, but also in the machine context. Now a large amount of my side projects are in C or Rust, and even my day job writing higher level languages has benefited greatly from the new ability to understand the moving parts. It's not going to give you a compsci education, but it'll give you that intermediate step you need to wade into that territory.

Re: A year with Go

#25
post #14
post #9

Earlier quoted context omitted.

What do you mean by "sets of types"? Traits in Rust handle more duties than interfaces do in Go, but in their role as interfaces the only difference is that Rust traits are explicitly implemented whereas Go interfaces are implicitly implemented (i.e. nominal types vs structural types).

Take the following example from Go: type ExInterface interface { ... } type ExStruct { arr []ExInterface } Each element of arr need not be the same type, so long as it implements ExInterface. In Rust, the only thing I can do that is similar is: struct ExStruct { arr: Vec , } Which means that each element of arr not only has to implement ExTrait, but also has to be of consistent type with the rest of the elements. If…

You can do that by storing `Box` in your vector. In fact, that's the equivalent of what Go does in your example.

Re: A year with Go

#26
post #14

Earlier quoted context omitted.

Take the following example from Go: type ExInterface interface { ... } type ExStruct { arr []ExInterface } Each element of arr need not be the same type, so long as it implements ExInterface. In Rust, the only thing I can do that is similar is: struct ExStruct { arr: Vec , } Which means that each element of arr not only has to implement ExTrait, but also has to be of consistent type with the rest of the elements. If…

You can do that by storing `Box ` in your vector. In fact, that's the equivalent of what Go does in your example.

That's fantastic to know. I might just switch back to rust because of this.

Re: A year with Go

#27
>Adding proper mutexes to some of our code in production slowed things down so much it was actually better to just run the service under daemontools and let the service crash/restart.

Can the author explain this bit some more? If adding mutexes slows down your code to the point where you would rather just deal with data corruption/races it seems to me that there are issues with your code, not the language.

Re: A year with Go

#28
post #8

Earlier quoted context omitted.

Erlang is probably the only true object-oriented language. http://www.infoq.com/interviews/johnson-armstrong-oop

> Erlang is probably the only true object-oriented language. And it's true because its creator says so right here, in this link!

Or because it does satisfy much of the Kay criteria for OO and encourages such programming styles.

Re: A year with Go

#29
post #12

Funny how HN was on the Go bandwagon just a few years ago, and now an article like this is almost unanimously upvoted (without much contrarian discussion(!)). I contributed to Go in the early phases and I really enjoyed using it and learning it, but I found myself going to either Java if I wanted to write something for production or Node if I wanted to write something as a prototype. Unfortunately, I haven't used it…

HN was the same about Node too. In a year we will see the same articles about Rust.

Re: A year with Go

#30
post #14
post #9

Earlier quoted context omitted.

What do you mean by "sets of types"? Traits in Rust handle more duties than interfaces do in Go, but in their role as interfaces the only difference is that Rust traits are explicitly implemented whereas Go interfaces are implicitly implemented (i.e. nominal types vs structural types).

Take the following example from Go: type ExInterface interface { ... } type ExStruct { arr []ExInterface } Each element of arr need not be the same type, so long as it implements ExInterface. In Rust, the only thing I can do that is similar is: struct ExStruct { arr: Vec , } Which means that each element of arr not only has to implement ExTrait, but also has to be of consistent type with the rest of the elements. If…

To elaborate a bit on the sibling comment here, Rust makes things a bit more explicit than Go does. A Go interface type is actually a pointer (of sorts), since you don't generally want to store things of different types and sizes in a single array. For example, if you have:

    type StructOne struct {
        field uint32
    }
    
    type StructTwo struct {
        field uint64
    }
It's pretty clear that these structures are of different size. Now, if both of these structures implement the "Foo" interface, we can't simply make an array like []Foo, since we'd have no practical method to index into the array. Go solves this by making []Foo actually be an array of pointers.

However, Rust's philosophy is, AFAIK, "be explicit about the cost you pay". So, if you want to make an "array of things that implement Foo", you need to explicitly put the "things" behind a pointer, or a Box. So, you get:

    struct MyStruct {
        arr: Vec>,
    }
Which makes it explicit that you're storing a "list of pointers to things that implement Foo". Of course, the nice part is that you can use generic syntax to make an array that doesn't use pointers, like so:

    struct MyStruct2 {
        arr: Vec,
    }
In the above, you can only store items of a single type in the `arr` field, and the generics constrain that to be only types `T` that implement Foo. The upside is, however, that you don't have any pointer indirection (and the compiler monomorphizes - i.e. generates new code for each generic implementation), so your code is probably faster / easier for LLVM to optimize.
Post reply on HN