Live data from Hacker News

Go subtleties

harrisoncramer.me

51–60 of 190 posts

Re: Go subtleties

#51

Go has certainly come a long ways from its initial mission to be a simple language for Rob Pike's simple coworkers. type User struct { Name string `json:"name"` Password string `json:"-"` Email string `json:"email"` } So you can specify how to serialize a struct in json using raw string literals containing arbitrary metadata. And json:"X" means to serialize it to X, except the special value "-" means "omit this one,"…

I never liked the concept of struct tags, it's a kind of stringly typed programming where the meaning of X or - depends entirely on what the json package says it means. An alternative is to introduce something like annotations, but I'm sure there will be resistance as it makes the language lean closer to e.g. Java. But my take on that is that if you want stricter typing like that, you should actually go to Java or C#…

"Stringly typed programming" is the phrase I was looking for. It's the equivalent of a shrug from the programming language designer: "I don't know what to do about that, so I'll just add a magic string and let someone else figure it out."

That and one or two other examples in the article smelled vaguely of PHP to me: features piled up in response to immediate needs instead of coherent design. For a language that famously refused to add generics for years (then did them badly, IMHO), it seems off-brand.

Re: Go subtleties

#52
post #19

As somebody who only views Go from a distance, I see this list as a combination of „what‘s the big deal?“ and „please don‘t“.

I'm amused by posts like this because it shows that Go is finally slowly moving away from being an unergonomically simplistic language (its original USP?) to adopt features a modern language should have had all along. My experience developing in it always gave me the impression that the designers of the language looked at C and thought "all this is missing is garbage collection and then we'll have the perfect languag…

I remember when I first got out of uni and did backend Java development, I thought I was incredibly productive because of the sheer amount of typing and code I had to pump out.

After doing a bit of frontend JS I was quickly dissuaded of that notion, all I was doing was writing really long boilerplate.

This was in the Java 6 days, so before a lot of nice features were added, for example a simple callback required the creation of a class that implements an interface with the method (so 3 unique names and a bunch of boilerplate to type out, you could get away with 2 names if you used an anonymous class).

Re: Go subtleties

#53
> The wg.Go Function

> Go 1.25 introduced a waitgroup.Go function that lets you add Go routines to a waitgroup more easily. It takes the place of using the go keyword, [...]

99% of the time, you don't want to use sync.WaitGroup, but rather errgroup.Group. This is basically sync.WaitGroup with error handling. It also has optional context/cancellation support. See https://pkg.go.dev/golang.org/x/sync/errgroup

I know it's not part of the standard library, but it's part of the http://golang.org/x/ packages. TBH, golang.org/x/ is stuff that should be in the standard library but isn't, for some reason.

Re: Go subtleties

#54

The time.After function creates a channel that will be sent a message after x seconds. Or, will it? https://github.com/golang/go/issues/24595 ... even though the value is nil, the type of the variable is a non-nil interface... Go "boxes" that value in an interface, which is not nil. This can really bite you if you return interfaces from functions Bit me when I was noob. These days, I fail build if ireturn fails. go i…

waitgroup's inadequacy is why I end up using structured concurrency like https://github.com/sourcegraph/conc

The last release of this was 2.5 years ago, and it's pre-1.0... is this really ready for production use?

Genuinely asking, I'm relatively new to Golang and would love to have a better sense of what parts of the ecosystem are worth learning about.

Re: Go subtleties

#55
post #19

Earlier quoted context omitted.

I'm amused by posts like this because it shows that Go is finally slowly moving away from being an unergonomically simplistic language (its original USP?) to adopt features a modern language should have had all along. My experience developing in it always gave me the impression that the designers of the language looked at C and thought "all this is missing is garbage collection and then we'll have the perfect languag…

More like, let's throw away the last 75 years of programming language theory advances, only to rediscover them again ourselves, with much hardship.

Sounds Like „Tell me about Generics in Go without telling me about Generics in Go“

Re: Go subtleties

#56
post #53

> The wg.Go Function > Go 1.25 introduced a waitgroup.Go function that lets you add Go routines to a waitgroup more easily. It takes the place of using the go keyword, [...] 99% of the time, you don't want to use sync.WaitGroup, but rather errgroup.Group. This is basically sync.WaitGroup with error handling. It also has optional context/cancellation support. See https://pkg.go.dev/golang.org/x/sync/errgroup I know it…

I thought exactly the same thing. I use errgroup in practically every Go project because it does something you'd most likely do by hand otherwise, and it does it cleaner.

I discovered it after I had already written my own utility to do exactly the same thing, and the code was almost line for line the same, which was pretty funny. But it was a great opportunity to delete some code from the repo without having to refactor anything!

Re: Go subtleties

#57
post #9

Ah the old nil values boxed into non-nil interfaces. Even after 8 years writing go code almost every day this still bites me occasionally. I've never seen code that actually uses this. I understand why it is the way it is but I hate it.

Yes, that'a bit too late after ten+ years perhaps but I wished we had a nil type and checking whether the interface is empty was a type assertion. In all other cases, like any(2) == 2, we compare the values. Then again that would mean that the nil identifier would be coerced into a typed nil and we would check for the nilness of what is inside an interface in any(somepointer) == nil. wrt the current behavior, it also…

> In all other cases, like any(2) == 2, we compare the values.

But any(nil) == nil returns true like you'd expect.

The reason that any((*int)(nil)) == nil is false is the same reason that any(uint(2)) == 2 is false: interfaces compare values and types.

Re: Go subtleties

#58
post #41

Earlier quoted context omitted.

If you think Go and C are that similar then you don't know either.

They are similar in the sense that there are very few abstractions, relying on the programmer to reimplement common patterns and avoid logical mistakes. You have to put thought into such things as: - Did I add explicit checks for all the errors my function calls might return? - Are all of my resources (e.g. file handles) cleaned up properly in all scenarios? Or did I forget a "defer file.Close()"? (A language like C+…

> Did I add explicit checks for all the errors my function calls might return?

You can easily check this with a linter.

> Are all of my resources (e.g. file handles) cleaned up properly in all scenarios? Or did I forget a "defer file.Close()"? (A language like C++ solved this problem with RAII in the 1980s)

You can forget to use `with` in Python, I guess that's also C now too eh?

> Does my Go channel spaghetti properly implement a worker pool system with the right semaphores and error handling?

Then stop writing spaghetti and use a higher level abstraction like `x/sync/errgroup.Group`.

Re: Go subtleties

#59

Earlier quoted context omitted.

More like, let's throw away the last 75 years of programming language theory advances, only to rediscover them again ourselves, with much hardship.

Sounds Like „Tell me about Generics in Go without telling me about Generics in Go“

No need to talk about generics when we can talk about something simple like the inability to implement type safe enums in Go.

Re: Go subtleties

#60

Earlier quoted context omitted.

If you think Go and C are that similar then you don't know either.

Go and C have partially shared origins. Two of the three creators of Go (Ken Thompson and Rob Pike) were involved in the early days of C. Ken Thompson is even the creator of B, the predecessor of C. There are obvious huge differences between the language but in a more subtle way they're actually quite similar: C is an "unergonomically simplistic language", just as the parent commenter describes Go.

Pike was not involved with the design of C. He was involved with Newsqueak and Limbo which inspired Go's concurrency model.
Post reply on HN