NHacker Next
  • new
  • past
  • show
  • ask
  • show
  • jobs
  • submit
Go 1.23 Released (go.dev)
hu3 154 days ago [-]
Opt-in telemetry. A very rare sight these days. Glad to see.

Not even Mozilla does that with Firefox [1].

> Starting in Go 1.23, the Go toolchain can collect usage and breakage statistics that help the Go team understand how the Go toolchain is used and how well it is working. We refer to these statistics as Go telemetry.

> Go telemetry is an opt-in system, controlled by the go telemetry command. By default, the toolchain programs collect statistics in counter files that can be inspected locally but are otherwise unused (go telemetry local).

> To help us keep Go working well and understand Go usage, please consider opting in to Go telemetry by running go telemetry on. In that mode, anonymous counter reports are uploaded to telemetry.go.dev weekly, where they are aggregated into graphs and also made available for download by any Go contributors or users wanting to analyze the data. See “Go Telemetry” for more details about the Go Telemetry system.

[1] "Firefox collects telemetry data by default. We collect this data to help improve the performance and stability of Firefox. Telemetry data is made up of two data sets: interaction data and technical data." - https://support.mozilla.org/en-US/kb/telemetry-clientid

traceroute66 154 days ago [-]
> Opt-in telemetry. A very rare sight these days. Glad to see.

Ahem. Cough.

Given Google's ties to Go, of course it was NOT opt-in when originally announced.

After, shall we say, a "lively" discussion on the relevant Github topic[1], it was changed to opt-in. :D

Opt-in is the correct stance.

[1]https://github.com/golang/go/discussions/58409

frosting1337 154 days ago [-]
But it is now, and that's good and should be applauded.
port19 154 days ago [-]
I don't believe the Go team deciding not to break GDPR law after massive backlash is anything that should be applauded.
frosting1337 153 days ago [-]
I'm not really understanding the logic here, but you do you bud.
euroderf 154 days ago [-]
I'd bet you dollars to donuts that the Go team originally asked for opt-in and got overruled by suits.
adonovan 154 days ago [-]
You have it backwards. The suits are way more comfortable with privacy violation than the Go team.
euroderf 154 days ago [-]
You have me backwards cos I had it forwards. I was unclear perhaps.

I meant (a) "someone" (suits?) said let's install telemetry, (b) the Go team said well hey come on let's make it opt-in rather than defaulting to "on", (c) suits said no we just sneak in the default "on" (cos google ebil).

adonovan 154 days ago [-]
Well I can assure you that is not what happened. Our team tried to come up with a telemetry design that set a higher bar for privacy preservation than the norms of the industry (including Google), something so safe that it would be acceptable to enable by default. Of course, the community rejected it and that plan died. But the "suits" at Google afford our team enough autonomy to act in the best interests of the Go community.

Google is not quite the monolithic James Bond villainy of your caricature.

euroderf 151 days ago [-]
Glad to hear.

FWIW I wasn't suggesting "villainy" so much as "SNAFU". Google's record on privacy in general leaves something to be desired.

bananapub 154 days ago [-]
there's infinity things to criticise google for, but "the go team want useful metrics" isn't one of them.
154 days ago [-]
kjs3 154 days ago [-]
There's the "If you have nothing to hide..." guy.
wsve 154 days ago [-]
I'm open to being convinced otherwise, but I feel like I'm the only one who doesn't get why opt-out telemetry is such a big deal.

Sure, if it's a software library, I don't want it doing random network calls during my runtime. That's just rude.

But if it's a user application (including a compiler), I don't see what the fuss is about. Of all the myriad of ways our data is harvested every single day, telemetry seems very unhelpful to advertisers and hackers, but very helpful to the people whose job it is to make the software you use better. I'd love to help them make the software I use better

kingsleyopara 154 days ago [-]
Privacy concerns aside, I personally don't appreciate binaries making network requests unless it's strictly required for them to function.
wsve 154 days ago [-]
Where is that line for you? Is occasionally checking for security updates strictly necessary? Is reporting a crash to the devs so they can fix it necessary? What about sending system & usage telemetry so they can prevent future bugs?
Zuiii 154 days ago [-]
For me, it's like GP said: Absolutely no unauthorized network traffic unless strictly required for the purpose of the software (e.g. curl). No security updates, crash reporting, telemetry unless you prompt the user and show the user exactly what will be sent (similar to how syncthing does it).

Anything less is voyeurism.*

* extreme language I know, but it's precisely how I feel about these acts.

justinclift 154 days ago [-]
> Where is that line for you?

None of the above is acceptable. Crash reporting can generate its output locally for people to manually send, if they choose to do so.

port19 154 days ago [-]
Do you know the definition of the word strictly? No, security and upstream convenience are not even remotely necessary for a tool to work
0cf8612b2e1e 154 days ago [-]
You don’t know what they are sending. Maybe today it is innocuous data. Tomorrow, they ship off your ssh keys.

Better to default deny all.

arp242 154 days ago [-]
A program that does not connect to the network at all today can also start shipping off your ssh keys tomorrow. Anything can always be added or changed.
justinclift 154 days ago [-]
Probably a higher chance of that being noticed though. ;)
mholt 154 days ago [-]
> Opt-in telemetry. A very rare sight these days.

Because it doesn't work. o:-)

(Introduces a slant/bias to the data.)

https://twi.github.io/blog/making-go-telemetry-opt-in-is-a-m...

tjoff 154 days ago [-]
Same with opt out.

Just have to accept that you are not going to get perfect data. And it doesn't excuse one to behave like an asshole.

LtWorf 154 days ago [-]
You forget that most people here work at startups that have compulsory telemetry.
154 days ago [-]
candiddevmike 154 days ago [-]
There was a lengthy discussion to persuade them to not have it on by default: https://github.com/golang/go/discussions/58409
rollcat 154 days ago [-]
Google can already see every installation of every Go program/package in existence, unless you set GOPROXY=direct (or a custom proxy). The default is to use https://proxy.golang.org, which is operated by Google.
ianlancetaylor 154 days ago [-]
The default proxy has a privacy policy: https://sum.golang.org/privacy.
tharax 154 days ago [-]
But better than this is would be if my go tooling didn't default to trying to pull codebases through a proxy

Forgive me for being cynical, but I don't like that out of the box the toolchain tries to pull all the code at `example.com/business/logic` through google servers.

delduca 154 days ago [-]
Until they decide it to be enabled by default.
eps 154 days ago [-]
Exactly. Give it a couple of releases and the default "for new installations" will be On. Two more releases and all other installs will be opted in. Classic pattern for shoveling stuff down the throat of resisting gray masses.
Foxboron 154 days ago [-]
At which point us, the Linux packagers and other package maintainers, is just going to patch it out. I wouldn't be very worried.
cma 154 days ago [-]
And Google makes you call it something other than Go, like Firefox did to linux packagers:

> The Go trademark and the Go Logo ( ) – collectively, the “Go Trademarks” – are trademarks of Google and are treated separately from the copyright license grants contained in the BSD-licensed Go repositories, as described below.

> Substantially unmodified distributions¶

> Substantially unmodified distributions may use the Go Trademarks if the derivative work complies with the terms of the Go programming language’s open source license and is made in a good faith attempt to replicate the quality and substance of the original project.

> Examples of modifications that would be considered substantially unmodified include language translation and localization, bug and security patches, and necessary interoperability/compatibility modifications.

> The Go Trademarks may be used in connection with such substantially unmodified distributions following the “Naming Conventions for Authorized Uses”.

> Substantially modified distributions may include explicit changes to functionality, interfaces, or features.

They can modify these trademark terms later too with a "backwards incompatible" change:

> Guideline Version¶

> These Trademark Guidelines are version 1.0 and may be followed by subsequent versions. These Guidelines may be edited for clarity; the major version will be increased when changes introduce new requirements, define new criteria, or otherwise present a backwards incompatible change.

Foxboron 154 days ago [-]
It's not 2006 anymore.
fngjdflmdflg 154 days ago [-]
I don't understand what you mean by this. Are you saying you can patch out telemetry in Linux package managers are Firefox doesn't care? What does that have to do with 2006? I think GP has a valid point otherwise as people will just install the thing named Firefox and not check to see if there is a telemetry free version going by a different name.
icholy 154 days ago [-]
Sir, you seem to have dropped your tinfoil hat.
rkharsan64 154 days ago [-]
It seems like the right way to respect a user's privacy, but opt-in telemetry just doesn't work.

I see the concerns as a user (and disable telemetry wherever I can), but at the same time if I were to add telemetry to my OSS project, I would either make it opt out, or just not add it at all.

The people who actually enable telemetry are a huge minority, and the data collected would be completely useless due to bias.

The best way, in my opinion, is to have completely unidentifiable telemetry (not sure if something like this even exists), or nothing at all.

slowmovintarget 154 days ago [-]
> The best way...

The best way is not to have telemetry at all. But then that's a user-centric take.

nalgeon 154 days ago [-]
If you find the official release notes a bit dry (they really are), I've prepared an interactive version with lots of examples:

- Iterators (range / types / pull / slices / maps).

- Timer changes (garbage collection and reset/stop behavior).

- Canonical values with the `unique` package.

- HTTP cookie handling.

- Copying directories.

- Slices and atomics changes.

https://antonz.org/go-1-23

danielvaughn 154 days ago [-]
Thank you for your service, this is awesome! I'd love to see language maintainers post interactive release notes like this.
metadat 154 days ago [-]
I want to understand the purpose of maps.All().

In the example:

  m := map[string]int{"a": 1, "b": 2, "c": 3}
  
  for k, v := range maps.All(m) {
   fmt.Printf("%v:%v ", k, v)
  }
  
  fmt.Println("")
  
  for k, v := range m {
   fmt.Printf("%v:%v ", k, v)
  }
These both output the same thing. What's the point of the addition?

Slices.All() seems similarly redundant and pointless.

Surely I must be misunderstanding something, I hope.

sakjur 154 days ago [-]
They’re useful because they let you pass a slice or map to something built to handle the new func(func (…) bool) style iterators.

If I create a IterateOver(fn func(func (K, V any) bool)) function, you cannot pass a slice since that doesn’t match fn’s type, but if you wrap it with slices.All it’ll work.

ianlancetaylor 154 days ago [-]
You can use it with other functions that use iterators. For example, here is code that makes a copy of a map keeping only the even keys.

  maps.Collect(xiter.Filter2(func(k, v int) bool { return k%2 == 0 }, maps.All(m)))
154 days ago [-]
felixge 154 days ago [-]
This is great, thank you.
monkfromearth 152 days ago [-]
[dead]
epage 154 days ago [-]
As someone who was advocating for a similar warning in Rust (finally added to clippy in 1.78), I'm glad to see this improvement in `go vet`

> The go vet subcommand now includes the stdversion analyzer, which flags references to symbols that are too new for the version of Go in effect in the referring file. (The effective version is determined by the go directive in the file’s enclosing go.mod file, and by any //go:build constraints in the file.) > > For example, it will report a diagnostic for a reference to the reflect.TypeFor function (introduced in go1.22) from a file in a module whose go.mod file specifies go 1.21.

progbits 154 days ago [-]
Don't most Rust crates solve this by running MSRV builds/tests?

Or is the goal to catch it eg. in precommit hook?

Expurple 154 days ago [-]
Clippy is both faster in the CI and can be integrated into an IDE feedback
fourseventy 154 days ago [-]
I don't like the "range-over-func" addition. I feel like it is adding complexity and syntactic sugar to the language that has thus far been mostly avoided.
thiht 154 days ago [-]
Hard disagree. A standard way to define iterators was long overdue, and using the existing `range` construct was the right solution.

This change will end up removing some mental load, at an extremely low complexity cost. Basically you define an iterator just by defining a function. No additional keyword, no state to manage, just a function.

TwentyPosts 154 days ago [-]
The first time I looked at the syntax, it honestly looked like gibberish to me.

It's probably simple, but the control flow just felt convoluted.

glzone1 154 days ago [-]
Are you talking about

for key, val := range m.Range

I like that a fair bit more than

m.Range(func(key, val any) bool {

candiddevmike 154 days ago [-]
But now I have to understand what m.Range does, and I can't assume it's a slice or a map etc. Prior to this change, you could almost always correctly assume what a for loop is doing as it was very primitive.

It's changes like this that will make Go less productive for users over time, IMO. Java-fication.

jerf 154 days ago [-]
You put your cursor on the "Range" portion of m.Range, and hit "Jump to Definition".

You can also just not import things that do crazy things with iterators. Based on the history of the community, that will actually be fairly easy. I'm yet to see anything crazy with generics get into a library that I use. I'm abundantly positive there's going to be a dozen "hey let's go do crazy things with rangefunc" libraries in the next couple of weeks, probably some will even make it to HN (with predictable comments bemoaning how complicated Go is getting even though these libraries have an expected use rate in the low dozens of people in the next few years), but the odds of them penetrating into common practice remain low. (Higher than previous attempts at such libraries, because rangefunc fixes some basic issues with them. But still low overall, I think.)

I think you could go many, many years programming Go in the next few years and not encounter any funny iterators in real code. If you just assume the iterator is doing what it looks like it should be doing and isn't doing anything funny, you're going to be 99%+ correct in the Go programming world.

mariusor 154 days ago [-]
> You put your cursor on the "Range" portion of m.Range, and hit "Jump to Definition".

Well, that's one reason why people usually run away from languages high in magic like Java/JS to something like Go: not needing a fancy IDE to make sense of what's happening with a single line of code.

bartonfink 154 days ago [-]
[flagged]
mariusor 154 days ago [-]
I'll agree with you that it is a very "mild" case of magic, or maybe this doesn't qualify as magic at all because Go doc is pretty good. But having to build the docs and then learning what m.Range does adds extra inconvenience to what until now was just an eyeball scan operation of the "for" line.
peterashford 154 days ago [-]
Unnecessarily agressive
saturn_vk 154 days ago [-]
Even if you don't have any help from an LSP, I don't really see how this change adds any meaningful complexity.

With `for x, y := range m.Range`, you know you are iterating over something, and you are getting an `x` and a `y`. For the purposes of understanding the range block and what it does, it doesn't really matter what `m.Range` is, only that it allows iteration. Just like you don't care in <=1.22 land whether `m.Range` is a slice, map, or channel, because for the purposes of understanding the code, that doesn't matter.

icholy 154 days ago [-]
You seem to have forgotten that it's possible to range over channels.
silisili 154 days ago [-]
Same. This is one of the first times I'd checked release notes and not really understood most of it at first glance.
cedws 154 days ago [-]
Not a fan either, this release feels like it’s shoehorning FP into Go.
icholy 154 days ago [-]
The change adds no syntax.
fourseventy 154 days ago [-]
"for key, val := range m.Range" is syntactic sugar for using the m.Range iterator directly "m.Range(func(key, val any) bool".

In a vacuum I think it's fine, but I don't want to see stuff like this getting added to the language routinely. I prefer a small language.

unscaled 154 days ago [-]
Go grew too big (in popularity) to be small. Popular languages tend to grow as the userbase grows. This is natural — the language gets used across a wider range of industries, and the programs being written in the language become larger, more mature and more diverse.

The language maintainers need to balance a small specification or a small implementation versus the users' demand, but in most cases at least some user demands win routinely. This is especially true when the language has just one major implementation. There is a significant cost for making that implementation more complex, but there is a more significant cost for making millions of programs that rely on a single implementation more complex just to make that implementation simpler.

pptr 154 days ago [-]
I think the key difference is that in a loop body you can return from the outer function. In a function passed to m.Range you can't.
tedunangst 154 days ago [-]
Go 1.22 is still right there.
minkles 154 days ago [-]
> Go telemetry is an opt-in system

Great job Go. Hat tip and respect for this. Unlike .Net. I will enable this where it is appropriate.

traceroute66 154 days ago [-]
> Great job Go. Hat tip and respect for this

Whoah. Easy there cowboy.

It was not opt-in when originally announced.

After an extended, shall we say, "lively" discussion on Github[1], they did the right thing and made it opt-in.

(N.B. The discussion was heavily moderated and redacted, it was even more "lively" at the time.)

[1]https://github.com/golang/go/discussions/58409

etse 154 days ago [-]
Are you opposed to the process by which discussion can initiate a transition from negative state to positive state?

Seems healthy to me.

synicalx 154 days ago [-]
To me, even proposing the (extremely obviously) negative state in the first place is a sign of bad faith on the part of the proposer.

If they proposed kicking puppies twice a day, and after some discussion decided to not do that would we all be applauding their decision?

heromal 148 days ago [-]
Ridiculous. Only you believe those two are equivalent.
synicalx 147 days ago [-]
I don't believe those two things are equivalent, that isn't the purpose of an analogy.
minkles 154 days ago [-]
[flagged]
neonsunset 154 days ago [-]
FWIW .NET tooling telemetry can be easily opted-out, which the SDK explicitly tells you about, and there is a page that has full list of the kind of data that is collected (CLI usage metrics and tooling crash stack traces). You can also review the metrics yourself.

About: https://learn.microsoft.com/en-us/dotnet/core/tools/telemetr...

Collected metrics: https://dotnet.microsoft.com/en-us/platform/telemetry

Source code: https://github.com/dotnet/sdk/tree/main/src/Cli/dotnet/Telem...

In either case, many teams have CIs with 'DOTNET_CLI_TELEMETRY_OPTOUT=1' and call it a day even if it makes no difference to them.

minkles 154 days ago [-]
[flagged]
efilife 154 days ago [-]
Where is it? I honestly want to know
maccard 154 days ago [-]
This is a great example of why it's utterly useless. In the link we're discussing, the release notes say:

> To help us keep Go working well and understand Go usage, please consider opting in to Go telemetry by running go telemetry on. In that mode, anonymous counter reports are uploaded to telemetry.go.dev weekly, where they are aggregated into graphs and also made available for download by any Go contributors or users wanting to analyze the data. See “Go Telemetry” for more details about the Go Telemetry system.

If someone who is genuinely interested in knowing where it is can't click one link for information, what chance do the go team have of people turning it on?>

rkharsan64 154 days ago [-]
From the release notes [1], which I think this post should actually point to:

> For backward compatibility, existing usages of //go:linkname found in a large open-source code corpus remain supported. Any new references to standard library internal symbols will be disallowed.

How does this work? Does the compiler have a whitelist of allowed uses?

[1]: https://go.dev/doc/go1.23

tedunangst 154 days ago [-]
The source has to be annotated to export the function.
rkharsan64 154 days ago [-]
Just confirming if I understand this correctly: they went through a big chunk of existing code, and then made any internal symbols used in that corpus accessible via //go:linkname?

I don't know why, but I (stupidly) assumed that they wouldn't allow new code to be written that uses those symbols, while allowing old code to work. :)

This explanation makes a lot more sense. So, you can keep using the symbols exposed with this change (until a future release hides/changes them), but cannot use any other internal symbol(s) anymore.

ianlancetaylor 154 days ago [-]
Yes.
scotthew1 154 days ago [-]
direct link to the release notes: https://go.dev/doc/go1.23
ptman 154 days ago [-]
And a different take on the changes: https://antonz.org/go-1-23/
divan 154 days ago [-]
boring <3
tmountain 154 days ago [-]
The way it should be.
ronsor 154 days ago [-]
Adding support for encrypted client hello to the TLS library is pretty exciting. I've been waiting a while for that.
euroderf 154 days ago [-]
I'd like to see a best-practices range-compatible depth-first preorder push iterator for a tree. Any tree implementation would do for purposes of exposition; for example package ast, where node order is important, unlike package filepath. FWIW there is current discussion in issue 64341 (and also 61405).
EdiX 154 days ago [-]
You could do:

    func inspect(n ast.Node) func(func(ast.Node) bool) {
        return func(f func(ast.Node) bool) {
            ast.Inspect(n, f)
        }
    }

used:

    for n := range inspect(f) {
        fmt.Printf("%T\n", n)
    }
euroderf 154 days ago [-]
OK, this works cos package ast already has `func Inspect`.

So how about a more general case ? A case where we do not have a `func Inspect` already in the stdlib ?

Maybe just replace it with (for example) `filepath.WalkDir` ?

38 154 days ago [-]
Why is it not dated?
154 days ago [-]
ffpip 154 days ago [-]
Any good resources on learning go?

Has anyone had any luck with the YT videos or courses way?

candiddevmike 154 days ago [-]
If you are familiar with programming, Tour of Go is a good overview of the language: https://go.dev/tour/
ffpip 145 days ago [-]
Thanks
aadhavans 154 days ago [-]
'Learning Go' by Jon Bodner [0] was the book I chose. A front-to-back reading got me up to speed with the language.

[0]: https://www.oreilly.com/library/view/learning-go-2nd/9781098...

DoctorOW 154 days ago [-]
I hope I don't sounds rude saying this but Go code is generally self evident. I personally got my Go knowledge from reading Go code on GitHub or the like. There's a certain beauty to Go code in that you can grasp what code does pretty easily, which definitely helps with learning.
wrs 154 days ago [-]
Go is superficially readable, but be careful. It has some (in my experience) quite non-evident semantic aspects, such as interface nils and channel “edge cases” (which aren’t “edge” at all, you do have to handle them). The Timer thing they just fixed is an example of how the Go core team really expects you to read the manual.

The good news is that the language and stdlib docs are concise and extremely clear. One of the really impressive things about Go.

rowanseymour 153 days ago [-]
I've been writing go for about 7 years and still occasionally footgun myself with nil interfaces. Drives me insane that they try so hard everywhere else to protect devs from themselves but that still exists.
maximus-decimus 154 days ago [-]
Maybe if all you want to do is read code, but if you want to write it you need to know stuff like the fact there's no inheritance or generics, that public methods are define with capital letters and to parse json you need to use magic annotations.
sapiogram 154 days ago [-]
You've clearly never opened Kubernetes' source code.
trevor-e 154 days ago [-]
I wouldn't say that's true, I personally find Go code more confusing to read than the average language. For example:

``` func (r rect) area() int { return r.width r.height } ```

This syntax is strange to me despite being a simple example. I can tell that it's a function that takes in a rect pointer, is maybe named area() (but I'm now confused why this definition doesn't have an argument?), and returns an integer value. I've tried reading larger Go files and constantly run into syntax confusion like this and get exhausted.

So sure, I understand the gist of this code, but this is more difficult to understand IMO than any Python, Ruby, Java, Swift, Rust, Gleam code I've read.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact
Rendered at 05:13:30 GMT+0000 (Coordinated Universal Time) with Vercel.