226 comments

[ 0.25 ms ] story [ 38.1 ms ] thread
I'm so glad the new uuid package landed - it's overdue but a very welcome addition! I've already replaced github.com/google/uuid with `uuid` in several projects
i'm glad this post that had 9 upvotes is being pushed to the top of the front page, unbiased
This makes me want to find a side project for an excuse to give Go another try (I last used it professionally pre-generics).

I do still wish it had discriminated unions (algebraic data types) and some better error handling ergonomics.

Do it. It is just a beautiful language to write and much simpler to pickup than many others. I am a fan boy of course but I love Go.
Go is extremely easy to pickup. If you know any language you probably know Go already for the most part (channels notwithstanding).

I wouldn't say it is a "beautiful" language however. Though that is in the eye of the beholder, I don't think the Go designers were even really going for beauty.

Tagged unions can be implemented in user code, you dont actually need language support to use them.

https://github.com/splizard/tagged

That is a LOT of code (very ugly code, I would add) that could be replaced by `type Float = float32 | float64` in a language with actual support for union types.
Tagged unions are not union types. A union type is a supertype for any arbitrary collection of types, but a tagged union is a single type with multiple data constructors, and does not require subtyping to be implemented.
Having worked a couple of greenfield go shops post generics, it’s still quite rare to find them in first party code. They’re just not that useful outside of library APIs. Proper algebraic data types would be a huge game changer.
I think you're gonna like it a lot more now. The language has gained a lot of nice things since they added generics
I have been waiting for generic methods and can't wait to use them!

The `go fix` modernisers are also great, have already run them in several repos.

I'm a big fan of `go fix`, such a nice thing for big projects
FYI golangci-lint and gopls are both broken if you try using generic methods.
Thank you for the headsup!
Broken how? Please report an issue. The latest gopls should support generic methods.
Ah my bad gopls is fine; I forgot to run

    go install golang.org/x/tools/gopls@latest
after upgrading Go itself.
I’ve been able to run golangci-lint locally just fine.

However I’ve not had much success running it on CI, with at least the 1.27rcs. I encountered some panic deep within staticcheck, and ended up turning off that specific linter on CI (better than not running it at all).

There was a tracking issue for go1.27 support at [1]. However that is now closed, which might imply that it should be working.

[1] https://github.com/golangci/golangci-lint/issues/6643

Nice additions to go.

I like to imagine that one day we'll have a language that launched with all the features languages eventually add. The whole ecosystem of packages would be built on them instead of a legacy of more primitive language feature sets.

I don’t think launching Go today would have been better than 15 years ago.

Standard ML is a perfect programming language from the 90s. It unfortunately does not have a great eco system of packages.

I mean one thing frontier models are really good at is porting code with pretty low level of supervision. Provided there are enough fans porting packages from other ecosystems should not be a big challenge.
No thanks. Reduced feature-set is the appeal.
> I like to imagine that one day we'll have a language that launched with all the features languages eventually add.

Don't most languages on the heap of languages nobody uses fulfill that?

> Second, a key in a struct literal may now be any valid field selector for the struct type, allowing fields in nested or embedded structs to be initialized directly

It's been a while since I've written more than anything trivial in golang, but this seems like a big deal to me. As in, I can define a struct that is consistent and reusable in other structs

This is quite a QoL issue, but is it big? Nothing changes from functional point of view.
It will be very nice working with code generators like oapi-codegen that can generate either nested structs or very unwieldy struct names. So big in that context, but like you said just a nice qol improvement most of the time.
If I'm being honest, I actually hate this feature. I like things being obvious, and structs were always something I could rely on being very explicit.
Every release CPU load becomes a bit lower. Love it :)
Keeping priorities right!
New JSON is amazing, and SIMD will be big for json, audio/video etc.
I have recently been spending time learning go, really really liking the language, awesome standard lib, excellent tooling and great experience.

It sounds like the dumbest thing in the world, but I love the import system auto-adding stuff inside of vscode when I need it. just slick.

I think the fact that package names are URLs is simultaneously genuis and horrifying.
I love how proactive the crypto team is about post quantum. They released https://pkg.go.dev/crypto/mldsa. The lead maintainer Filippo Valsorda wrote a nice piece here[1] to urge the tech world to start deploying good enough versions of post quantum crypto.

[1] https://words.filippo.io/crqc-timeline/

While I'm highly sympathetic to competing priorities crowding out movement to pq cryptography. At the same time it's not sudden at all. It's been 10 years since nist first said "move shit over"?
Yes, and at that time the answer was "move over where?" now it's 2026 and x-wing is a draft still
Ah. This is a bold faced lie. There were plenty of options in 2016. Nist released final candidates in 2024 and published the candidates this year.

ssh (as noted in tfa) has had pq defaults since 2022.

In case you wanted to know, the expression is actually "bald-faced lie", i.e. unmasked, shameless.
They are also lying, it is an Italics-Faced lie... thank you, I will see myself out. =3
If we wanted to make things really clear, we'd use strikethrough text for the lies!
"bold-faced lie" and "bald-faced lie" are both valid expressions. The original expression is "bare-faced lie" but they're all pretty similar to each other.
bold-faced lie is just the usual English drift that was actually questioned as incorrect when it first surfaced. If a lie is bold, you don't have to suggest that the user's face is bold when doing it. You can in thirty seconds of google searching find numerous sources explaining that "bold-faced" is a malapropism.
It's the usual English drift perhaps, but "bold faced lie" has been used since the 17th century, which is also apparent from "thirty seconds of Google searching". Three hundred years is enough usage for me to count it as correct.

On a side note, "bold faced" does not mean the persons face is bold, only that it is said boldly, which implies a level of rudeness that "bald-faced" or "bare-faced" does not.

Colloquialisms and slang have unstable meaning over history, location, and cultures.

Generally, something to be avoided by people striving for clearer communication. =3

> Generally, something to be avoided by people striving for clearer communication

Their communication seemed pretty clear to me. If anyone actually claims that they didn't understand what they meant but would have understood it by using the other form of the expression, I think that's a bold-faced lie.

That it has been used does not imply it was used equivalently, or with the same acceptance.

You're probably referencing https://english.stackexchange.com/questions/137551/bald-face... — but see in particular the "Update" section of the top answer.

Modern references seem to align (for instance, Garner's): Bald-faced and bare-faced have slightly different connotation than bold-faced. Despite "bold-faced lie" being in somewhat common use, "bald-faced lie" is more common (over 2x according to google stats), and overwhelmingly agreed upon as the "literate" choice, unless an author intends to refer to the sort of lie that would headline an article.

Yes but only one of them makes most people who hear it think you don’t know the expression you’re trying to use. There’s no objective reason it has to be this way, but it is, and at least personally I appreciate being told when I’ve got something stuck to my back.
I don't really know why I should care what expression I'm trying to use (or what someone else is trying to use) as long as the intent is understood. If anything, people who are needlessly pedantic about the way I express things that they clearly understood are people I'm happy to get signal from so that I can minimize my need to interact with them going forward; it's much nicer to find out from something inane like this than to wait until we have a communication problem about something actually important.
Calling it a lie is pretty heavy.
Yeah the deadline to move everything is drawing near I am actually not impressed by how fast things are going but all progress is good.
its ok we are still rawdogging ftp every day in the business world. The fax machines of the future truly
The .NET team have been similarly busy on post-quantum lately, it completely dominated the .NET API reviews for the dotnet 11 release.

It seems there's a big push happening behind the scenes.

Ok, but when is it coming to our web browsers and email clients?
I don't know about mail clients, but it's in most web browsers already.
Then I'm wondering why they don't simply use the same crypto libraries as the web browsers.
Go features cleaner crypto APIs (than OpenSSL for example) with less footguns.
Chromium uses BoringSSL, which opens its readme as follows:

> BoringSSL is a fork of OpenSSL that is designed to meet Google's needs.

> Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing so is likely to be frustrating because there are no guarantees of API or ABI stability.

OpenSSL itself is a clusterfuck that doesn't really meet anyone's needs: https://cryptography.io/en/latest/statements/state-of-openss...

It’s been on by default for 2 years in Chrome.
US Government is starting to push hard so code first needs to support it.
And Java implementations as well.
This person was public on the recent nist list against hybrid solutions. I simply don't understand why they would oppose the safer option. Yes I've read the mailing list, it just all seems quite suspicious.
> First, generic methods are now supported > Generic functions can now be used without explicit type arguments

Great! This was an ergonomic code issue I hit when trying to create a universal handler/controller generic that could hydrate/populate function arguments (from a request body) without having an actual copy of the arguments: https://github.com/xeoncross/mid/blob/main/handler.go#L12

Neat, stealing this.
I wrote a blog on it if you're interested: https://xeoncross.com/2026/better_go_handlers.html
Thanks for the link, looks like a very pleasant framework to use! I was interested to see "Mid-fasthttp" on the slower end in the benchmarks at the bottom, do you know why that is?

Btw, the Gin and Echo examples reference an "input" variable but it doesn't seem to be defined there? Maybe it was intentional, since the examples are just to give a general idea of how the handler looks in each library, but thought I would let you know just in case it wasn't.

Due to the fact that fasthttp is not net/http compatible it is due to the conversion being required from a https://pkg.go.dev/net/http#Handler. It was included for information purposes as I though someone would be curious.
Can proper Result/Option types be created for Go now?
You can do pipelined option/result manipulation now, but without sum types/pattern matching it's not going to be quite as useful as Rust's.
I love Go because even minor versions deliver great value like this. The struct literal inits and generic methods are great conveniences to clean up clumsy boilerplate.

Not to mention it’s just a dream language to work with , especially when building concurrent applications. I love engaging all of my cores. And memory is so expensive nowadays

Minor versions are basically major versions for Go. They’ll “never” create a Go v2 because they prioritise maintaining backwards compatibility as a language feature, thus following semver rules, no majors.
true that, but we get a couple of these a year it seems, so their overall velocity is excellent, and without breaking anything. a dream language.
Brace for a wave of drive-by pull-requests swapping google/uuid [1] out for the now-standard uuid package [2].

Kubernetes project will be the first one [3] I guarantee it.

[1] https://pkg.go.dev/github.com/google/uuid

[2] https://go.dev/pkg/uuid

[3] https://github.com/kubernetes/kubernetes/blob/2220c3853a2402...

will 'go fix' take care of this?
I don't think it ever suggests anything specific to 3rd-party packages
Unfortunately for people SELECTing UUIDs out of a DB directly into a uuid struct, the built-in uuid structs don't implement the necessary interface for that, so you'll have to continue using the google package, or a plain string.
Oooof… well played go team, well played.
Or just a number (128-bit).
The database/sql package gained native support[1] for the uuid.UUID type so it will Just Work even without the methods. This probably should have been mentioned in the release notes and database/sql package docs.

[1] https://cs.opensource.google/go/go/+/refs/tags/go1.27.0:src/...

Doesn’t the type name uuid.UUID violate go’s style guide for type naming? I seem to recall a fairly specific prohibition on stutter-types.
No. What else could it reasonably be named? Hard to imagine.

The rule has always been intended to cover types that have another word in them but still choose to pointlessly repeat the package name.

`uuid.UUIDGenerator` is a hypothetical example of the anti-pattern that would instead be better named as `uuid.Generator`.

> No. What else could it reasonably be named? Hard to imagine.

Ocaml often just has it be T

so uuid.T

Repeating the package name is fine if it's exactly the same name (modulo capitalization) and there's nothing better to name the type anyway. The style issue would arise with e.g. uuid.UUIDVersion, which should just be named uuid.Version. There used to be a gopls lint that would flag names like uuid.UUID but it got relaxed awhile ago.
Yeah, I would have gone with uuid.V4 or something. But oh well, as long as it works. :D
V4 or V7 are just how you initialize them (constructor), but then this the same representation, so they don't need specific types.
uuid.UUID is implemented as [16]byte, like most other UUID implementations out there.

If you want to keep your package implementation agnostic, use [16]byte as argument type; that's assignment-compatible with any other type that is such an array underneath:

For an example, see the UUID logging of golog: https://pkg.go.dev/github.com/domonda/golog#Message.UUID

Not mentioned: Floating-point parsing and formatting now uses Russ Cox's uscale algorithm.

https://research.swtch.com/fp

https://github.com/golang/go/blob/go1.27.0/src/internal/strc...

I’m so happy Russ still contributes even though he isn’t lead anymore. I always enjoy reading his blog posts
One of my engineering highlights was Russ reviewing a few of my contributions to Golang (to the core http library). He's a super cool and nice guy. I don't really write that much Go anymore, but it was a fun & cute language when it first came out.
I once wrote him an email asking what font was used in the plan9 papers. He replied. It's Lucida Sans Unicode. He even provided a url to paper published by the maker of the font.
I’d love to see how that compares to zmij: https://github.com/dtolnay/dtoa-benchmark
The upstream fmtlib dtoa-benchmark integrates uscale (https://fmtlib.github.io/dtoa-benchmark/results/). It uses C code from Russ Cox's original fpfmt repository (https://github.com/rsc/fpfmt/tree/main/bench/uscalec), which is slightly different from the Go code upthread.

Zmij and xjb are in a league of their own. Broadly speaking, dtoa first has to find the shortest decimal representation of the floating-point input, and then format that decimal representation into a string. Zmij and xjb pull far ahead of the others mostly by speeding up the second part of that process.

uscale is quite good without the stringification, as are many other algorithms. I would say uscale's main strength isn't its speed, but rather its simplicity and, more importantly, the fact that it does both formatting and parsing using a single ~11 KiB table, which no other algorithm offers (although yy comes close).

The core of newer methods like yy, xjb and zmij is remarkably simple: https://vitaut.net/posts/2026/yy-dtoa/. Shortest uscale is basically Schubfach or, rather, it's variant called Teju Jagua and has 2-3 wide multiplications compared to 1 for newer methods.

The complexity is optional and comes from squeezing the last few nanoseconds =).

Right, that's basically what I was trying to say (in so many words). I learned a lot from your dtoa blog posts and Zmij's implementation. Thank you!

> has 2-3 wide multiplications compared to 1 for newer methods.

As written, the `shortFloat()` function always calls `uscale()` two times, followed by an optional third call. Each `uscale()` does two wide multiplications (one full 64x64->128 and one 64x64->hi64, in case we want to make that distinction), so that works out to either 4 or 6 wide multiplications in total. I think `shortFloat()` could be rewritten to always do exactly 2 wide multiplications (both 64x64->128) at the cost of some more ALU operations. However, I don't see how that could be further reduced to only one wide multiplication without significantly altering the algorithm.

I seriously wonder why this isn't mentioned in release notes.
The SIMD stuff is incredible. I have been having lots of fun with it. You can use LLMs as a scalar to SIMD transpiler, it works amazingly well.

Sure a SIMD expert writing assembly can probably do a better job than an LLM using these new intrinsics, but it’s still massively faster.

I still believe that SIMD support is one of the most underrated new features in Go.

It's relatively straightforward to read and to write code using Go's SIMD package (the caveat being that you have to convert your data to SoA manually), and it gives comparable performance to other languages, since there's little in the way of GC overhead, bounds checking, etc, in this case.

So SIMD not only increases performance on its own, but it also closes the performance gap between Go and C++ / Rust, which has been a major cause for rewrites in the past. The memory usage overhead due to GC doesn't go anywhere of course, so there are still performance reasons to "Rewrite in Rust", but it's now become much easier to just optimise the hell out of Go code instead.

Are rewrites from Go to Rust for performance reasons really that common?
Hard to say tbh, but there are some high-profile examples, e.g. from Discord: https://discord.com/blog/why-discord-is-switching-from-go-to...
This was one of the times where it made some sense. A lot of their complaints were about GC, which Discord has had issues with in the past on other things. Notably, Discord switched from Cassandra to ScyllaDB for their messages, and cited the Java GC as a big reason.
I think it only really happens when companies run into GC problems
Odin solves this by letting you declare all arrays as either normal (AoS) or SoA, which helps with this use case a lot. Otherwise very similar ideas, except all the memory goodies. Underrated language!
Yeah, Odin's auto-SoA looks nice indeed
Wasn't Go supposed to be "simple"? I remember how Go advocates used to boast about not having generics and now it almost seems like Go is trying to become some sort of C# or Java Frankenstein. I'm not even trying to badmouth Golang - just legitimately confused.
A problem was so many others were screaming about the lack of generics, as though there were not other language options that provided them.
> almost seems like Go is trying to become some sort of C# or Java Frankenstein

The original Go team was trying to avoid this:

"Java, JavaScript (ECMAScript), Typescript, C#, C++, Hack (PHP), and more [...] actively borrow features from one another. They are converging into a single huge language." [0]

That team has since moved on, and now Go has begun to join that convergence.

The problem is that most programmers seem to want to write Java, more-or-less. New, simpler languages come along, but once they get popular, the pressure is on to turn them into Java-likes. It happened to Python and now it’s happening to Go. It takes a strong will for language maintainers to say “no”, and their language will suffer in popularity as a result - see, for example, Ruby.

[0] https://go.dev/talks/2015/simplicity-is-complicated.slide#5

I would argue that languages like Java (C#, Kotlin, etc.) strike a very good compromise between modeling ability and comprehension, which is why they are popular and people gravitate toward them.

You can have more complex languages like Scala that provide stronger modeling ability, but at the cost of complexity. Golang started off as extremely naive/simplistic, and is now converging in some ways. But it still has a ways to go: no generics on interfaces, no unions/ADTs, no pattern matching, no proper enums, error handling leaves much to be desired, and much more.

One can hope that the Go maintainers won't keep caving as they did for generics.
Go genetics are still incredibly simple compared to languages with a rich type system.
I'm pretty sure there is a silent majority of Go users who don't want/need/know about generics.
And they can simply not use them ?
Indeed ! So I don't see what the problem is here...
Go - the language no one likes, but frankly everyone needs.
Python is already the language everyone needs.
I love Go and would not enjoy working with any other language as much
idk, hn is the only place I every see people actually not liking go and most times those are people who's job is just far away from fields go is being use in.
Can't relate, I love Go
I love these release notes but I really wish they would add syntax highlighting to the Go blog. I'm always a little bit surprised/disappointed whenever I land on a go.dev link since I know the code will be just a little harder to visually parse than it needs to be.
There's a reason for this. Rob Pike was asked about it and said that syntax highlighting reminds him of the bright colors of children's toys and he personally disables it so that he can focus on the text.

I don't know why it's still like that but that's the original reasoning.

that's an extremely odd explanation and it makes me think that he has some hidden PTSD. it's also insane that one person's preference trumps the rest of the world's.
I understand and respect this position. I think syntax highlighting is a highly subjective matter, bordering on personal preference with regard to shell interactions, editor configurations, bindings, shortcuts, snippets, and the like. It's also... insignificant somehow, like quibbles over formatting rules that Go settled once and for all with `go fmt`.

I often prefer not to enable syntax highlighting just for color. Occasionally I'd choose some minimal theme that only highlights string literals and keywords. So it has two or three colors. But some of the color schemes I see are a festival of lights where every special element of syntax has its own color. I don't understand how that is supposed to help me parse anything and why the rules are complex. The `range` keyword needs to be purple, and `chan` must be navy blue. Why exactly? And every site has a different color scheme? There is no consensus, and there shouldn't be.

For a serious community-driven project like Go, dealing with the question of syntax highlighting is strange. The creators deliberately avoided the questions of IDEs and editors for Go, leaving them to the community. I think the same principle applies here.

What is childish is holding up one guy's editor preferences as a religious sacrament when 99.9% of your readers have different preferences.
Well, there's kind of a precedent at least...

> Gofmt's style is no one's favorite, yet gofmt is everyone's favorite.

That's been a major success
It basically revolutionized the entire industry and thank god.

Opinionated standard formatting is now the default.

Unlike formatting preferences, the colours I use in my editor don't effect others. That said I might not mind living in a world where everyone used the same highlighting scheme, as long as it was reasonable ;)
I just have a tampermonkey profile for go.dev to fix that for me.
When I started learning Go I went all in including using the recommended editor (acme editor) which has no syntax highlighting, no autocomplete and a very different way of writing code. My production went down a lot but the quality of the code went up a lot.

I think the lack of syntax highlighting was one reason for that. It makes you think more about the code you write and how it should compose, while a fully fledged IDE encourages you to just throw more code at the problem.

I think the ACME way should be used for love of code and ideally when you want to create libraries that stand the test of time. When you just want to get things done fast bring the full IDE and now some LLM vibes and it’s done.

[delayed]
I think there's a lot of value to be gained from turning all modern day features off for once and just code "raw", no syntax highlighting, just typing out all the code. Doesn't even need to be your own code, manually transfering code over can also help a lot with your basic coding skills.

I think a lot of people lose this over time because it's easier to use templates, autocomplete and LLMs, work from a higher level. But it's nice to go back to basics. Consider also firing up Pico-8 and writing some really really bad code. It's got a very rudimentary editor, 40 columns of code, no syntax highlighting, and you're limited in how much total code you can write. It also helps with leetcode since a lot of leetcode uses game coding tricks like modulo operators, min/max/clamp, etc (that's as far as I got, don't judge).

The Go official web site doesn't even use the Go fonts: https://go.dev/blog/go-fonts

I wonder if the Go fonts has been created just to get a trademark on the "Go" word...

The Go language is by itself more than enough to get a trademark. They only additional thing you can do with a font is get a design patent... for the font.

It's more likely that they don't feel the need to use the font they gave you (for your code editor) on code samples on their own web pages. As it's a custom font, the text would be susceptible to pop-in, or would visibly switch from one font to another, both of which are ugly.

Their CSS says this:

    #blog .Article[data-slug='/blog/go-fonts'] code {
      font-family: 'Go Mono', monospace;
    }
    #blog pre,
    #blog code {
      font-family: monospace;
    }
So they have no specific font preference for code samples, they only show their Go-specific font on the blog post about it. They prefer fast loading and no jank over custom font.
I get the why, kind of - if you need colors to make sense of code, maybe the code isn't clear enough. If you send blobs of code through email and other systems that don't necessarily have syntax highlighting, it also makes sense. But on a website, whyever not?

Personally I can't say when I was last actually aware of syntax highlighting. The only time I'm actively engaged with it is to change the default low contrast comment color that a lot of themes have (for some reason, as if comments are unimportant / noise) to something better. For Go, I don't really notice when it has or doesn't have syntax highlighting, at least not on e.g. go's website.

Quarterly reminder that Go still exists.
The release cycle is semi-annually.
Used to code primarily in Java. Now my app stack is about 80% Go. I love that it enables lightweight application development. Glad to see the platform evolving with a focus on resource efficiency.
Same. Go feels like the language that does everything I like about Java with a lot more control than Java gives
does it have goroutine termination, i recently found out you need a runtime patch for it
What exactly do you mean by "goroutine termination"?
I suppose: a "go" returns an id, and then you call kill(id) to terminate it, as if it were a pthread or a process. In which case the answer is: no.
Non-cooperatively terminating a shared-memory thread is an inherently unsafe thing to do, and basically every runtime that has an API for it regards it as a design mistake. See, e.g., https://docs.oracle.com/javase/8/docs/technotes/guides/concu... and https://learn.microsoft.com/en-us/windows/win32/api/processt.... (POSIX's pthread_cancel is somewhat different, and avoids some of the worst failure modes, but at the cost of not actually consistently killing the thread when you call it—and it still has a lot of problems besides that.) So I don't think Go is ever going to add this, nor should it.

(Having the go statement return a handle that you can block on would of course be completely fine, but at this point they're probably not going to do that either.)

(comment deleted)
Can just pass it a context, cancel the context, and handle for it in the goroutine.
The rule is to start a goroutine only if you know how it will end.

A goroutine that has to be killed (no other way to tell it to stop) is a bug.

Terminated from the outside? No. The only way is to have a communication channel or a context that can be canceled and a proper handling of these.
You can't terminate goroutines like individual threads, but there's no good reason to anyway. They designed the context system to be able to signal across goroutines and do cleanup that way
No. You're down a very bad path if you 're seeking that.