HN user

typical182

663 karma
Posts12
Comments77
View on HN

Go modules did not get rid of vendoring. You can do 'go mod vendor' and have been able to do so since Go modules were first introduced.

How long the google-run module cache (aka, module proxy or module mirror) at https://proxy.golang.org caches the contents of modules is I think slightly nuanced.

That page includes:

Whenever possible, the mirror aims to cache content in order to avoid breaking builds for people that depend on your package

But that page also discusses how modules might need to be removed for legal reasons or if a module does not have a known Open Source license:

proxy.golang.org does not save all modules forever. There are a number of reasons for this, but one reason is if proxy.golang.org is not able to detect a suitable license. In this case, only a temporarily cached copy of the module will be made available, and may become unavailable if it is removed from the original source and becomes outdated.

If interested, there's a good overview of how it all works in one of the older official announcement blog posts (in particular, the "Module Index", "Module Authentication", "Module Mirrors" sections there):

https://go.dev/blog/modules2019#module-index

They may be an expert in Go, but from their writing they appear to be misunderstanding (or at least misrepresenting) how things work in other languages

Thanks for that link.

Based on reading through that whole discussion there just now and my understanding of the different ecosystems, my conclusion is that certainly people there are telling Filippo Valsorda that he is misunderstanding how things work in other languages, but then AFAICT Filippo or others chime in to explain how he is in fact not misunderstanding.

This subthread to me was a seemingly prototypical exchange there:

https://lobste.rs/s/exv2eq/go_sum_is_not_lockfile#c_d26oq4

Someone in that subthread tells Filippo (FiloSottile) that he is misunderstanding cargo behavior, but Filippo then reiterates which behavior he is talking about (add vs. install), Filippo does a simple test to illustrate his point, and some others seem to agree that he is correct in what he originally said.

That said, YMMV, and that overall discussion does certainly seem to have some confusion and people seemingly talking past each other (e.g., some people mixing up "dependents" vs. "dependencies", etc.).

There’s some more context in a proposal from the folks behind this project to upstream the needed Go runtime hooks into Go proper.

From what I can tell, the core Go team seems generally favorable to it, so seems like a decent chance it will happen.

From:

#73608 proposal: all: add bare metal support

https://github.com/golang/go/issues/73608

Go applications built with GOOS=none would run on bare metal, without any underlying OS. All required support is provided by the Go runtime and external driver packages, also written in Go.

And:

These hooks act as a "Rosetta Stone" for integration of a freestanding Go runtime within an arbitrary environment, whether bare metal or OS supported.

Go 1.25 Release Notes 11 months ago

The arena experiment was essentially placed on indefinite hold:

The proposal to add arenas to the standard library is on indefinite hold due to concerns about API pollution.

I think the parent comment was using arenas as an example that GOEXPERIMENTs don't always move forward (like arenas), or can change while still GOEXPERIMENTs in a way that would normally not be allowed due to backward compatibility (like synctest).

The arena GOEXPERIMENT has not yet been dropped as of Go 1.25, but as I understand it, the plan is to remove arenas from the runtime when 'regions' are introduced, which have similar performance benefits but a much lower API impact:

https://github.com/golang/go/discussions/70257

As discussed there, seeing how people actually used the arena GOEXPERIMENT influenced the 'regions' design.

The biggest problem is any string you pass as an argument to the fmt functions is moved onto the heap

FWIW, that's not quite correct. For example, a string literal passed as a fmt argument won't be moved to the heap.

The upcoming Go 1.25 release has some related improvements that help strings in more cases. See for example https://go.dev/cl/649079.

Bluesky and atproto seem to be built to be hackable.

Someone in the community recently built a searchable directory of Bluesky "Starter Packs" (which are a way for a user to publish a set of interesting people & feeds to follow, primarily to help newcomers bootstrap their experience):

https://blueskydirectory.com/starter-packs/all

Dan Abramov posted about it earlier today, saying he liked it and:

"the fact that it can be done in the ecosystem is awesome. let the ecosystem cook" [1]

And maybe more poignantly:

"seeing random projects pop up in the atproto ecosystem reminds me just how much public web common were stifled by social companies closing down their APIs. an entire landscape of tools given up on and abandoned" [2]

[1] https://bsky.app/profile/danabra.mov/post/3lar3sdna222d

[2] https://bsky.app/profile/danabra.mov/post/3lar3xpuu4c2d

you can simply forbid pointers into the stack. This means that your GC doesn't need to be moving. I believe that's what Go does

I might have misunderstood your comment, but FWIW, Go does allow pointers into the stack from the stack.

When resizing/moving/copying a stack, the Go runtime does indeed find those pointers (via a stack map) and adjust them to point to the new stack locations. For example:

https://github.com/golang/go/blob/b25f5558c69140deb652337afa...

(The growable stacks I think replaced the segmented stacks circa Go 1.3 or so; I can't speak to whether they were contemplating growable stacks in the early days whilst considering whether to start their project with the Plan 9 toolchain, LLVM, or GCC, but to your broader point, they were likely considering multiple factors, including how quickly they could adapt the Plan 9 toolchain).

The “Personal” in PDS doesn’t mean it is only for self-hosting.

Bluesky has a main PDS instance at https://bsky.social that serves almost all of the Bluesky user base.

There is a good overview of the architecture here:

https://blueskyweb.xyz/blog/5-5-2023-federation-architecture

Here’s a snippet from the protocol roadmap they published 3-4 weeks ago [1]:

Multiple PDS instances

The Bluesky PDS (bsky.social) is currently a monolithic PostgreSQL database with over a million hosted repositories. We will be splitting accounts across multiple instances, using the protocol itself to help with scaling.

[1] https://atproto.com/blog/2023-protocol-roadmap

Effectively yes.

A fix for the loop variable closure problem is now in the official proposal process, which is how language changes happen in Go.

It’s a concrete proposal from the core Go team and seems to be on track for acceptance:

https://github.com/golang/go/issues/60078

An implementation is already available on tip and in the upcoming Go 1.21 release behind a GOEXPERIMENT flag.

The community reaction has been extremely positive. As one approximate measure, an earlier draft of the proposal had 671 upvotes and with 0 downvotes:

https://github.com/golang/go/discussions/56010

Generics seemingly split the community. May be some libraries won’t get used because they picked the wrong side.

I haven't really observed that at all.

One thing that is going on is there hasn't been a massive disruption while everyone stops to rewrite the world in generics, and generics are not suddenly everywhere, which is what some people had predicted would happen. I think part of the reason is that in some cases another solution (closures or interfaces or whatever) can be a better fit, and the evolutionary approach to generics that Go took means you can use generics in conjunction with non-generic libraries or other pre-existing approaches without suffering from an ecosystem split.

goda[0] is excellent. You do do things like:

  # show the impact of cutting any package
  goda cut ./...:all   
which prints a sorted ASCII table with stats like 'size:4.4MB loc:134171' for each package, which is an estimate the savings you'd get if you eliminated that package from your binary. That is a great way to see what is unexpectedly large compared to its value.

goda has a bunch of other capabilities around dependency analysis, and was written by long-time Go contributor Egon Elbre. The examples in the README are the best way to get started after 'go install github.com/loov/goda@latest'.

[0] https://github.com/loov/goda

There is a pretty complete description of the origination of UTF-8 here:

https://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt

Rob Pike opens with:

Looking around at some UTF-8 background, I see the same incorrect story being repeated over and over. The incorrect version is: 1. IBM designed UTF-8. 2. Plan 9 implemented it.

That's not true. UTF-8 was designed, in front of my eyes, on a placemat in a New Jersey diner one night in September or so 1992.

This seems to be a nice example of maintainers of a popular open source project listening to feedback from the broader community:

Thanks to everyone who took the time to write constructive, helpful feedback. Those discussions are open source at its best.

FWIW, there is a proposal to add telemetry to LLVM [0] and Rust used to have telemetry [1], both off by default. Some things in the node.js world have telemetry enabled by default, like Next.js [3].

Some people are posting here as if this is already decided -- AFAICT, that's not the case. It's not even a formal proposal yet, and the stated intent was to start a conversation around something concrete. (For context, this is standard for how the Go project approaches large topics, including for example I think there were something like ~8 very detailed generics design drafts from the core Go team over ~10 years).

It sounds like the Go team is going to take some time to look into some of the alternative approaches suggested in the feedback collected so far.

In any event, this is obviously a topic people are very passionate about, especially opt-in vs. opt-out, but I guess I would suggest not giving up hope quite yet.

[0] https://discourse.llvm.org/t/rfc-lldb-telemetry-metrics/6458...

[1] https://github.com/rust-lang/rustup/issues/341

[2] https://nextjs.org/telemetry

FWIW, people had started to post obscene ASCII drawings, were using various curse words, and there were many, many repetitive comments across the ~400 comments posted.

From what I understand of the conversation there, the core Go team said they were going to take some time to digest the feedback, including [0]:

The goal here is a productive conversation that aims at better understanding of different positions. Many comments here have contributed to that, and I am grateful for them. To be extra clear, the people who have been discussing opt-in vs opt-out respectfully and with reasoned arguments are most welcome here and have been an important part of the signal, not the noise. Thank you to them in particular.

Much of the moderation is being done by volunteer contributors working valiantly to keep the conversation on track, polite, useful, and non-repetitive. I appreciate their efforts.

This discussion has in fact scaled somewhat beyond what GitHub discussions can reasonably manage (I just spent a while clicking every "load more" link on the page to make ^F work again), which is causing even more repetition, so I will probably lock the discussion at the end of the day and take some time to think about the feedback we've gathered so far.

[0] https://github.com/golang/go/discussions/58409#discussioncom...

For open source projects in general, and the Go project in particular, I think it is easy to underestimate how much maintainer time is consumed discussing & considering whether a change should be made.

the ban prevents me from discussing the matter further

Hi ddevault, FWIW, in May 2022 on that #44577 issue [0] you had opened, it looks like someone on the core Go team commented there [1] recommending that you email the golang-dev mailing list or email them directly.

Separately, it looks like in July 2022, in one of the issues tracking the new friendlier -reuse flag, there was a mention [2] of the #44577 issue you had opened. In the normal course, that would have triggered an automatic update on your #44577 issue... but I suspect because that #44577 issue had been locked by one of the community gardeners as "too heated", that automatic update didn't happen. (Edit: It looks like it was locked due to a series of rapid comments from people unrelated to Sourcehut, including about “scummy behavior”).

Of course, communication on large / sprawling open source projects is never quite perfect, but that's a little extra color...

[0] https://github.com/golang/go/issues/44577

[1] https://github.com/golang/go/issues/44577#issuecomment-11378...

[2] https://github.com/golang/go/issues/53644#issuecomment-11751...

Some people today raised concerns about disabling background refreshes (the temporary workaround originally suggested by the Go team) as having possibly unacceptable resulting performance for end users...

...but it sounds like disabling background refreshes would have strictly better end-user performance than what the Sourcehut team had been planning as described in their blog post today (GOPRIVATE and whatnot)?

Hi Steve, first, thanks for weighing in here!

I might have misunderstood your comment, but in my GP comment I was indeed attempting to contrast 'go install foo@latest' with 'cargo install foo', which both install binaries. (I wasn't talking about 'go get bar@latest', which now is just for updating or adding dependencies to a project).

Also, I'm contrasting what happens by default at the moment either binary install command is run. My understanding is Cargo's (non-default) 'cargo install --locked foo' behavior is similar to the default behavior of 'go install foo@latest'. In other words, the default behavior is fairly different between 'cargo install foo' (without --locked) vs. 'go install foo@latest'.

I edited my GP comment to simplify the example to use 'foo' in both cases. Maybe that helps?

In that same section, the blog describes the behavior of 'go install foo@latest' and contrasts it to how the default install "in some ecosystems bypass pinning."

That is also a difference in default behavior between Go and Cargo.

To install a 'foo' binary, 'go install foo@latest' gives you the latest version of foo, but the direct and indirect dependencies used are the versions listed in foo's go.mod or a dependency’s go.mod file (and not whatever the latest versions of those direct and indirect dependencies might be at the moment the install is invoked).

'cargo install foo' supports the optional --locked flag, but its not the default behavior: [1]

By default, the Cargo.lock file that is included with the package will be ignored. This means that Cargo will recompute which versions of dependencies to use, possibly using newer versions that have been released since the package was published. The --locked flag can be used to force Cargo to use the packaged Cargo.lock file if it is available.

There are definitely pros and cons here, but to my knowledge it is not "just NPM" that is being contrasted in the blog.

Finally, I'm no world-class Rust expert, but I like using Cargo. I think Cargo is a fantastic tool that set the bar for package mangers, and it has done great things for the Rust community. But it is easier for communities to learn from each other with a base understanding of where & why different choices have been made, which is part of what is behind some of my comments around Go's behavior. ;-)

[1] https://doc.rust-lang.org/cargo/commands/cargo-install.html

The default way Go handles go.mod is fairly different than the default way Cargo handles Cargo.lock files, including for example with libraries.

Also, when the blog says:

Moreover, when a dependency is added with go get, its transitive dependencies are added at the version specified in the dependency’s go.mod file, not at their latest versions, thanks to Minimal version selection.

I believe that is significantly different than default Cargo behavior and for example default 'pub' behavior for Flutter (though I know approximately nothing about Flutter package management beyond a cursory search just now ;-)

To my knowledge, both Cargo and Flutter 'pub' prefer the most recent / highest allowed version by default when asked to solve constraints, whereas Go does not.

Cargo: [1]

When multiple packages specify a dependency for a common package, the resolver attempts to ensure that they use the same version of that common package, as long as they are within a SemVer compatibility range. It also attempts to use the greatest version currently available within that compatibility range.

Flutter 'pub': [2]

For each package in the graph, pub looks at everything that depends on it. It gathers together all of their version constraints and tries to simultaneously solve them. (Basically, it intersects their ranges.) Then it looks at the actual versions that have been released for that package and selects the best (most recent) one that meets all of those constraints.

[1] https://doc.rust-lang.org/cargo/reference/resolver.html

[2] https://dart.dev/tools/pub/versioning#constraint-solving