oh god i'm going to become poor
Signed-off-by: Xe Iaso <me@christine.website>
This commit is contained in:
parent
c5cbcc47ec
commit
b3bdb9388a
|
@ -8,12 +8,11 @@ tags:
|
||||||
- modules
|
- modules
|
||||||
---
|
---
|
||||||
|
|
||||||
I've been using Go since Go 1.4. Since I started using Go so long ago, I’ve
|
I've been using Go since Go 1.4. Since I started using Go then (2014-2015 ish),
|
||||||
seen the language evolve significantly. The Go I write today is roughly the same
|
I’ve seen the language evolve significantly. The Go I write today is roughly the
|
||||||
Go as the Go I wrote back when I was still learning the language, but overall
|
same Go as the Go I wrote back when I was still learning the language, but the
|
||||||
it’s evolved and changed into something similar yet different feeling in
|
toolchain has changed in ways that make it so much nicer in practice. Here are
|
||||||
practice. Thinking back over the years, here are some of the biggest ticket
|
the biggest things that changed how I use Go on a regular basis:
|
||||||
items that really changed how I use Go on a daily basis:
|
|
||||||
|
|
||||||
* The compiler rewrite in Go
|
* The compiler rewrite in Go
|
||||||
* Go modules
|
* Go modules
|
||||||
|
@ -27,11 +26,11 @@ today. Without having met the people I did in the Go slack, I would probably not
|
||||||
have gotten as lucky as I have as consistently as I have.
|
have gotten as lucky as I have as consistently as I have.
|
||||||
|
|
||||||
Releasing a "Go 2" has become a philosophical and political challenge due to the
|
Releasing a "Go 2" has become a philosophical and political challenge due to the
|
||||||
forces that be. "Go 2" has kind of gotten the feeling of “this is never going to
|
forces that be. "Go 2" has kind of gotten the feeling of "this is never going to
|
||||||
happen, is it?” with how the political forces within and without the Go team are
|
happen, is it?" with how the political forces within and without the Go team are
|
||||||
functioning. They seem to have been incrementally releasing new features and
|
functioning. They seem to have been incrementally releasing new features and
|
||||||
using version gating in `go.mod` to make it easier on people instead of a big
|
using version gating in `go.mod` to make it easier on people instead of a big
|
||||||
semver-breaking release.
|
release with breaking changes all over the standard library.
|
||||||
|
|
||||||
This is pretty great and I am well in favour of this approach, but with all of
|
This is pretty great and I am well in favour of this approach, but with all of
|
||||||
the changes that have built up there really should be a Go 2 by this point. If
|
the changes that have built up there really should be a Go 2 by this point. If
|
||||||
|
@ -41,15 +40,16 @@ only to make no significant changes and tag what we have today as Go 2.
|
||||||
of salt the size of east Texas. I am not an expert in programming language
|
of salt the size of east Texas. I am not an expert in programming language
|
||||||
design and I do not pretend to be one on TV. I am also not a member of the Go
|
design and I do not pretend to be one on TV. I am also not a member of the Go
|
||||||
team nor do I pretend to be one or see myself becoming one in the
|
team nor do I pretend to be one or see myself becoming one in the
|
||||||
future. <br /><br />If you are on the Go team and think that something I said
|
future.<br /><br />If you are on the Go team and think that something I said
|
||||||
here was observably wrong, please [contact me](/contact) so I can correct it. I
|
here is demonstrably wrong, please [contact me](/contact) so I can correct it. I
|
||||||
have tried to contain my personal feelings or observations about things to these
|
have tried to contain my personal feelings or observations about things to these
|
||||||
conversation snippets.</xeblog-conv>
|
conversation snippets.</xeblog-conv>
|
||||||
|
|
||||||
This is a look back at the huge progress that has been made since Go 1 released
|
This is a look back at the huge progress that has been made since Go 1 released
|
||||||
and what I'd consider to be the headline features of Go 2. Most of this is a
|
and what I'd consider to be the headline features of Go 2.
|
||||||
whirlwind tour of over a half-decade of improvments to the Go compiler, toolchain
|
This is a whirlwind tour of the huge progress in improvement to the Go compiler,
|
||||||
and standard library. I highly encourage you read this fairly large post in chunks
|
toolchain, and standard library, including what I'd consider to be the headline
|
||||||
|
features of Go 2. I highly encourage you read this fairly large post in chunks
|
||||||
because it will feel like _a lot_ if you read it all at once.
|
because it will feel like _a lot_ if you read it all at once.
|
||||||
|
|
||||||
## The Compiler Rewrite in Go
|
## The Compiler Rewrite in Go
|
||||||
|
@ -59,9 +59,9 @@ team has a background in Plan 9 and C was its lingua franca. However as a result
|
||||||
of either it being written in C or the design around all the tools it was
|
of either it being written in C or the design around all the tools it was
|
||||||
shelling out to, it wasn’t easy to cross compile Go programs. If you were
|
shelling out to, it wasn’t easy to cross compile Go programs. If you were
|
||||||
building windows programs on a Mac you needed to do a separate install of Go
|
building windows programs on a Mac you needed to do a separate install of Go
|
||||||
from source with other targets enabled. This worked, it wasn’t the default
|
from source with other targets enabled. This worked, but it wasn’t the default
|
||||||
though and eventually the Go compiler rewrite in Go changed this so that Go
|
and eventually the Go compiler rewrite in Go changed this so that Go could cross
|
||||||
could cross compile natively with no effort required.
|
compile natively with no extra effort required.
|
||||||
|
|
||||||
<xeblog-conv name="Cadey" mood="enby">This has been such an amazingly productive
|
<xeblog-conv name="Cadey" mood="enby">This has been such an amazingly productive
|
||||||
part of the Go toolchain that I was shocked that Go didn’t have this out of the
|
part of the Go toolchain that I was shocked that Go didn’t have this out of the
|
||||||
|
@ -70,6 +70,13 @@ point where Go didn’t have the easy to use cross-compiling superpower it
|
||||||
currently has, and I think that is a more sure marker of success than anything
|
currently has, and I think that is a more sure marker of success than anything
|
||||||
else.</xeblog-conv>
|
else.</xeblog-conv>
|
||||||
|
|
||||||
|
<xeblog-conv name="Mara" mood="happy">The cross compliation powers are why
|
||||||
|
Tailscale uses Go so extensively throughout its core product. Every Tailscale
|
||||||
|
client is built on the same Go source tree and everything is in lockstep with
|
||||||
|
eachother, provided people actually update their apps. This kind of thing would
|
||||||
|
be at the least impossible or at the most very difficult in other languages like
|
||||||
|
Rust or C++.</xeblog-conv>
|
||||||
|
|
||||||
This one feature is probably at the heart of more CI flows, debian package
|
This one feature is probably at the heart of more CI flows, debian package
|
||||||
releases and other workflows than we can know. It's really hard to understate
|
releases and other workflows than we can know. It's really hard to understate
|
||||||
how simple this kind of thing makes distributing software for other
|
how simple this kind of thing makes distributing software for other
|
||||||
|
@ -105,19 +112,19 @@ time.</xeblog-conv>
|
||||||
## Go Modules
|
## Go Modules
|
||||||
|
|
||||||
In Go's dependency model, you have a folder that contains all your Go code
|
In Go's dependency model, you have a folder that contains all your Go code
|
||||||
called the GOPATH. The GOPATH has a few top level folders that have a well-known
|
called the `GOPATH`. The `GOPATH` has a few top level folders that have a
|
||||||
meaning in the Go ecosystem:
|
well-known meaning in the Go ecosystem:
|
||||||
|
|
||||||
* bin: binary files made by `go install` or `go get` go here
|
* bin: binary files made by `go install` or `go get` go here
|
||||||
* pkg: intermediate compiler state goes here
|
* pkg: intermediate compiler state goes here
|
||||||
* src: Go packages go here
|
* src: Go packages go here
|
||||||
|
|
||||||
GOPATH has one major advantage: it is ruthlessly easy to understand the
|
`GOPATH` has one major advantage: it is ruthlessly easy to understand the
|
||||||
correlation between the packages you import in your code to their locations on
|
correlation between the packages you import in your code to their locations on
|
||||||
disk.
|
disk.
|
||||||
|
|
||||||
If you need to see what `within.website/ln` is doing, you go to
|
If you need to see what `within.website/ln` is doing, you go to
|
||||||
GOPATH/src/within.website/ln. The files you are looking for are somewhere in
|
`GOPATH/src/within.website/ln`. The files you are looking for are somewhere in
|
||||||
there. You don’t have to really understand how the package manager works (mostly
|
there. You don’t have to really understand how the package manager works (mostly
|
||||||
because there isn’t one). If you want to hack something up you just go to the
|
because there isn’t one). If you want to hack something up you just go to the
|
||||||
folder and add the changes you want to see.
|
folder and add the changes you want to see.
|
||||||
|
@ -169,7 +176,7 @@ choice that people really wanted solid guidance and defaults on. After a while
|
||||||
they changed this to default to `~/go` (with an easy to use command to influence
|
they changed this to default to `~/go` (with an easy to use command to influence
|
||||||
the defaults without having to set an environment variable). I don't personally
|
the defaults without having to set an environment variable). I don't personally
|
||||||
understand the arguments people have for wanting to keep their home directory
|
understand the arguments people have for wanting to keep their home directory
|
||||||
"clean", but the arguments are valid regardless.</xeblog-conv>
|
"clean", but their preferences are valid regardless.</xeblog-conv>
|
||||||
|
|
||||||
Overall I think GOPATH was a net good thing for Go. It had its downsides, but as
|
Overall I think GOPATH was a net good thing for Go. It had its downsides, but as
|
||||||
far as these things go it was a very opinionated place to start from. This is
|
far as these things go it was a very opinionated place to start from. This is
|
||||||
|
@ -197,11 +204,11 @@ such repository hosting sites.
|
||||||
The main disconnect between importing from a GOPATH monorepo and a Go library
|
The main disconnect between importing from a GOPATH monorepo and a Go library
|
||||||
off of GitHub is that when you import from a monorepo with a GOPATH in it, you
|
off of GitHub is that when you import from a monorepo with a GOPATH in it, you
|
||||||
need to be sure to import the repository path and not the path used inside the
|
need to be sure to import the repository path and not the path used inside the
|
||||||
repository. This sounds weird but this is the difference between importing
|
repository. This sounds weird but this means you'd import
|
||||||
`github.com/Xe/x/src/github.com/Xe/x/markov` and `github.com/Xe/x/markov`. This
|
`github.com/Xe/x/src/github.com/Xe/x/markov` instead of
|
||||||
means that things need to be extracted _out of_ monorepos and reformatted into
|
`github.com/Xe/x/markov`. This means that things need to be extracted _out of_
|
||||||
“flat” repos so that you can only grab the one package you need. This became
|
monorepos and reformatted into "flat" repos so that you can only grab the one
|
||||||
tedious in practice.
|
package you need. This became tedious in practice.
|
||||||
|
|
||||||
In Go 1.5 (the one where they rewrote the compiler in Go) they added support for
|
In Go 1.5 (the one where they rewrote the compiler in Go) they added support for
|
||||||
[vendoring code into your
|
[vendoring code into your
|
||||||
|
@ -317,10 +324,14 @@ dependencies in it. It allows you to have `within.website/ln@v0.7` and
|
||||||
`within.website/ln@0.9` as dependencies for _two different projects_ without
|
`within.website/ln@0.9` as dependencies for _two different projects_ without
|
||||||
having to vendor source code or do advanced GOPATH manipulation between
|
having to vendor source code or do advanced GOPATH manipulation between
|
||||||
projects. It also adds cryptographic checksumming for each Go module that you
|
projects. It also adds cryptographic checksumming for each Go module that you
|
||||||
download from the internet. This allows you to avoid having to shell out to
|
download from the internet, so that you can be sure the code wasn't tampered
|
||||||
`git` every time you fetch a module that someone else has fetched before.
|
with in-flight. They also created a cryptographic checksum comparison server so
|
||||||
Companies could run their own Go module proxy and then use that to provide
|
that you could ask a third party to validate what it thinks the checksum is so
|
||||||
offline access to Go code fetched from the internet.
|
you can be sure that the code isn't tampered with on the maintainer's side. This
|
||||||
|
also allows you to avoid having to shell out to `git` every time you fetch a
|
||||||
|
module that someone else has fetched before. Companies could run their own Go
|
||||||
|
module proxy and then use that to provide offline access to Go code fetched from
|
||||||
|
the internet.
|
||||||
|
|
||||||
<xeblog-conv name="Mara" mood="hmm">Wait, couldn't this allow Google to see the
|
<xeblog-conv name="Mara" mood="hmm">Wait, couldn't this allow Google to see the
|
||||||
source code of all of your Go dependencies? How would this intersect with
|
source code of all of your Go dependencies? How would this intersect with
|
||||||
|
@ -332,10 +343,9 @@ disadvantages out of the gate with Go modules. I think that in practice the
|
||||||
disadvantages are limited, but still the fact that it defaults to phoning home
|
disadvantages are limited, but still the fact that it defaults to phoning home
|
||||||
to Google every time you run a Go build without all the dependencies present
|
to Google every time you run a Go build without all the dependencies present
|
||||||
locally is kind of questionable. They did make up for this with the checksum
|
locally is kind of questionable. They did make up for this with the checksum
|
||||||
verification database a little, but it's still kinda sus.
|
verification database a little, but it's still kinda sus.<br /><br />I'm not
|
||||||
|
aware of any companies I've worked at running their own internal Go module
|
||||||
I'm not aware of any companies I've worked at running their own internal Go
|
caching servers, but I ran my own for a very long time.</xeblog-conv>
|
||||||
module caching servers, but I ran my own for a very long time.</xeblog-conv>
|
|
||||||
|
|
||||||
The earliest version of Go modules basically was a glorified `vendor` folder
|
The earliest version of Go modules basically was a glorified `vendor` folder
|
||||||
manager named `vgo`. This worked out amazingly well and probably made
|
manager named `vgo`. This worked out amazingly well and probably made
|
||||||
|
@ -401,10 +411,10 @@ Semantic Import Versioning has always been a part of Go modules and the Go team
|
||||||
is now refusing to budge on this.
|
is now refusing to budge on this.
|
||||||
|
|
||||||
<xeblog-conv name="Cadey" mood="coffee">My suggestion to people is to never
|
<xeblog-conv name="Cadey" mood="coffee">My suggestion to people is to never
|
||||||
release a version `1.x.x` of a Go project to avoid the “v2 landmine”. The Go
|
release a version `1.x.x` of a Go project to avoid the "v2 landmine". The Go
|
||||||
team claims that the right bit of tooling can help ease the pain, but this
|
team claims that the right bit of tooling can help ease the pain, but this
|
||||||
tooling never really made it out into the public. I bet it works great inside
|
tooling never really made it out into the public. I bet it works great inside
|
||||||
google3 though!</xeblog-conv>
|
Google's internal monorepo though!</xeblog-conv>
|
||||||
|
|
||||||
When you were upgrading a Go project that already hit major version 2 or
|
When you were upgrading a Go project that already hit major version 2 or
|
||||||
higher to Go modules, adopting Go modules forced maintainers to make another
|
higher to Go modules, adopting Go modules forced maintainers to make another
|
||||||
|
@ -436,7 +446,7 @@ could have two versions of the same C functions try to be linked in and this
|
||||||
really just does not work.</xeblog-conv>
|
really just does not work.</xeblog-conv>
|
||||||
|
|
||||||
Overall though, Go modules has been a net positive for the community and for
|
Overall though, Go modules has been a net positive for the community and for
|
||||||
people wanting to create reliable software in Go. It’s just such a big semantic
|
people wanting to create reliable software in Go. It’s just such a big semantics
|
||||||
break in how the toolchain works that I almost think it would have been easier
|
break in how the toolchain works that I almost think it would have been easier
|
||||||
for the to accept if _that_ was Go 2. Especially since the semantic of how the
|
for the to accept if _that_ was Go 2. Especially since the semantic of how the
|
||||||
toolchain worked changed so much.
|
toolchain worked changed so much.
|
||||||
|
@ -614,8 +624,7 @@ that would normally be compile time errors into runtime errors.
|
||||||
<xeblog-conv name="Cadey" mood="coffee">I say this as someone who maintains a
|
<xeblog-conv name="Cadey" mood="coffee">I say this as someone who maintains a
|
||||||
library that uses contexts to store [contextually relevant log
|
library that uses contexts to store [contextually relevant log
|
||||||
fields](https://pkg.go.dev/within.website/ln) as a way to make logs easier to
|
fields](https://pkg.go.dev/within.website/ln) as a way to make logs easier to
|
||||||
correlate between.
|
correlate between.<br /><br />Arguably you could make the case that people are misusing the
|
||||||
Arguably you could make the case that people are misusing the
|
|
||||||
tool and of course this is what will happen when you do that but I don't know if
|
tool and of course this is what will happen when you do that but I don't know if
|
||||||
this is really the right thing to tell people.</xeblog-conv>
|
this is really the right thing to tell people.</xeblog-conv>
|
||||||
|
|
||||||
|
@ -629,13 +638,11 @@ really neat if contexts could be goroutine-level globals so you didn’t have to
|
||||||
one of the major arguments I remember hearing against them was that contexts
|
one of the major arguments I remember hearing against them was that contexts
|
||||||
"polluted" their function definitions and callsites. I can't disagree with this
|
"polluted" their function definitions and callsites. I can't disagree with this
|
||||||
sentiment, at some level it really does look like contexts propagate "virally"
|
sentiment, at some level it really does look like contexts propagate "virally"
|
||||||
throughout a codebase.
|
throughout a codebase.<br /><br />I think that the net improvements to
|
||||||
|
reliability and understandability of how things get stopped do make up for this
|
||||||
I think that the net improvements to reliability and understandability of how
|
though. Instead of a bunch of separate ways to cancel work in each individual
|
||||||
things get stopped do make up for this though. Instead of a bunch of separate
|
library you have the best practice in the standard library. Having contexts
|
||||||
ways to cancel work in each individual library you have the best practice in
|
around makes it a lot harder to "leak" goroutines on accident.</xeblog-conv>
|
||||||
the standard library. Having contexts around makes it a lot harder to "leak"
|
|
||||||
goroutines on accident.</xeblog-conv>
|
|
||||||
|
|
||||||
## Generics
|
## Generics
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue