Recent submissions

Comment · 2 months ago
The “runtime” as in the compiler runtime which provides the scheduler, garbage collector, etc.
Comment · 3 months ago
Many comments on generic methods. Perhaps this example will help understand a hopefully not-too-objectionable case of using them in practice.

The math/rand/v2 package has a number of functions which return random numbers of a certain type:

    i := rand.Int32()  // a random signed 32-bit integer (type int32)
    j := rand.Uint64() // a random unsigned 64-bit integer (type uint64)
It has functions which return a number within a range:

    in := rand.Int32N(10)   // a random int32 in the range [0,10)
    jn := rand.Uint64N(100) // a random uint64 in the range [0,100)
It also has a generic function, rand.N, where the return type is set by a type parameter. The definition of rand.Int32N (for comparison) and rand.N are:

    func Int32N(n int32) int32
    func N[Int intType] (n Int) Int
Adding some spaces to make the common elements align (apologies if my formatting gets mangled), that's:

    func Int32N               (n int32) int32
    func N      [Int intType] (n Int  ) Int
As you can see, the generic function N has the same signature as the non-generic Int32N, except the type it operates on is set by a type parameter (named "Int"). The type parameter has a constraint, intType, which is a private type defined in the math/rand package. (There's nothing magic about this constraint, it's just a list of all the integer types in the language, and you can write it yourself if you want to. It's a separate type to keep the function signature of N from becoming too large, and it's internal to math/rand because it doesn't need to be part of the public package API.)

The nice thing about rand.N is that it lets you write something like this:

    // d is a random time.Duration in the range [0, 10 minutes)
    d := rand.N(10 * time.Minute)
Without generics, you'd instead write this as the following, which is a lot more noise:

    d := time.Duration(rand.Int64N(int64(10 * time.Minute)))
The generic rand.N has a more confusing type signature and a lot more language complexity behind it, but the code using it is simpler and easier to read. We think that's a good tradeoff, but of course not everyone will agree.

All the functions I've mentioned so far use a default random number source. Each of them also exists as a method of the rand.Rand type, which generates numbers from a user-provided randomness source. For example:

    rng := rand.New(rand.NewChaCha8(seed))
    a := rng.Uint64()
    b := rng.Uint64N(100)
There is one exception, though: Until Go 1.27, there was no Rand.N method, because we did not support generic methods. (A generic type could have methods, but those methods could not be further type parameterized.)

In Go 1.27, there is now a Rand.N method:

    // Using a ChaCha8-based source with a defined seed,
    // generate a duration in the range [0, 10 minutes).
    rng := rand.New(rand.NewChaCha8(seed))
    d := rng.Duration(10 * time.Minute)
This method's signature is:

    func (r *Rand) N[Int intType](n Int) Int
Comparing function vs. method and generic vs. concrete:

    func           Int32N               (n int32) int32 // function
    func           N      [Int intType] (n Int  ) Int   // generic function
    func (r *Rand) Int32N               (n int32) int32 // method
    func (r *Rand) N      [Int intType] (n Int)   Int   // generic method
In this case, generic methods permit us to fix a small wart in the package API. This example isn't the motivating reason for adding generic methods, but I think it serves as an example of how adding them makes the language a bit simpler and more consistent. In Go, methods are just a type of function. Previously, you could write a type-parameterized function, but you couldn't write a type-parameterized method. That's an inconsistency that you need to remember. Now you can write type-parameterized functions or methods, using a consistent syntax for either.

Type-parameterized methods don't participate in interface satisfaction, so this change isn't without its own subtleties. Discussing the tradeoffs there would double the length of this post, and weighing them is why it took so long for us to decide to add generic methods.

Another possibility is that people will use generic methods to write unreadably complex code. My personal opinion is that nothing will stop people from writing unreadably complex code if they want to; the fix to complexity is to not do that.

Comment · 5 months ago
Fair enough, but that leaves us with no way to represent zone IDs in URLs at all. Neither http://[fe80::4%eth0]/ nor http://[fe80::4%25eth0]/ is valid under RFC 3986.

Given that net/url has supported RFC 6874 since before RFC 9844 came along, our choices are:

* Keep supporting the RFC 6874 syntax.

* Drop support for it, require strict RFC 3986, have no support for zone IDs in URLs at all. Breaks existing users, utterly infeasible.

* Stop supporting RFC 6875 and start supporting an unescaped % as the zone ID separator, which conforms to no standard I know of. Also breaks existing users, infeasible.

* Some sort of hybrid where we try to support both %25 and % as a separator? Ugh.

Of these, keeping the existing support as-is until or unless a new standard comes along seems like the best option.

Comment · 5 months ago
> In theory, there is guidance for how to properly handle IPv6 zones in user interfaces in RFC 9884, but there's no such guidance for URLs.

RFC 6874: Representing IPv6 Zone Identifiers in Address Literals and Uniform Resource Identifiers (https://www.rfc-editor.org/rfc/rfc6874.html)

Which says that, yes, you need to %-encode the %, so a URL containing a host of fe80::4%eth0 becomes http://[fe80::4%25eth0]/. Yes, that's ugly. Sorry.

> TL;DR: computers were a mistake.

I agree entirely.

(For what it's worth, I am a maintainer of Go's net/url package, and I believe net/url correctly handles zone ids in URLs. It's always possible there's something wrong I'm not aware of. Please let me know if there is!)

Comment · 7 months ago
Mint (T-Mobile MVNO) has been great for me, $20/month/line and my one experience with international travel was good ($20 for 10 days). I used to be on Verizon and the quality of service doesn’t seem any worse while the price is dramatically lower.
Comment · 7 months ago
Sounds ridiculous, but worked on mine! So far, the fix has stuck, too.
Comment · 9 months ago
Much more prosaic (if slightly embarrassing), I'm afraid: The update was non-trivial (this CL is simple, but there are some accompanying ones in x/text which are not) and it didn't hit the top of the priority list for anyone who understands x/text.

Go is pretty much entirely developed in public; there are some Google-internal customizations but none of them are particularly exciting and almost all changes start in the open source repo and are imported from there.

Comment · 9 months ago
To be very pedantic, there are two separate services: The module proxy (proxy.golang.org) serves cached modules and makes no guarantees about how long cache entries are kept. The sum database (sum.golang.org) serves module checksums, which are kept forever in a Merkle tree/transparency log.
Comment · 11 months ago
0600 and 0_600 are octal literals:

    octal_lit      = "0" [ "o" | "O" ] [ "_" ] octal_digits .
Comment · 1 year ago
In my experience, the Apple Watch blood oxygen monitoring was horribly inaccurate. It would report wildly variable results, often telling me that I had a blood oxygen level of 80% (which, if true, would indicate that I should be getting myself to an emergency room ASAP).

Regular pulse oxygen meters are cheap and reliable.

Comment · 1 year ago
It means we're not confident the API is stable yet. There might be further changes before the final, non-experimental version, depending on user feedback and further experience with the current proposal.

In the case of encoding/json/v2, enabling GOEXPERIMENT=jsonv2 has two major effects:

1. It flips encoding/json (the original, not /v2) to use the new implementation. This is supposed to be a fully backwards-compatible change, modulo some changes to the text of some errors. We're very interested to hear of any cases of existing programs breaking when the experiment is turned on, because (aside from the aforementioned error text, which you shouldn't be depending on) it likely indicates a bug that needs fixing. This is the "new code, please test" half of the change.

2. It enables the new API (encoding/json/v2, encoding/json/jsontext, some new options in encoding/json). This is the "unstable API, might change in response to feedback" half of the change.

Comment · 1 year ago
> I really don't like how this article claims that the primary issue with Go's error handling is that the syntax is too verbose.

I don't believe this claim is made anywhere.

We've decided that we are not going to make any further attempts to change the syntax of error handling in the foreseeable future. That frees up attention to consider other issues (with errors or otherwise).

Comment · 1 year ago
I have a 2024 Kia EV6, and this is pretty much what it does: Central screen displays CarPlay, backup camera, and infrequently-used settings controls, dials and knobs for most things, one secondary touchbar (row of buttons, but it’s really a touchscreen so the buttons can change) for climate controls. Pretty much perfect, although only wired CarPlay. (The 2025 models apparently have wireless.)
Comment · 1 year ago
> I say this not to be flippant or sarcastic but rather to ask how our ancestors seemed fine with the above but we seem less so?

Because by and large our female ancestors raised the children, were offered no choice in whether to raise the children, and their opinions of the situation were not recorded.

Comment · 1 year ago
The "move a branch from one commit to another without changing anything" command is "git reset".

"git reset --hard" is "...and also change all the files in the working directory to match the new branch commit".

"git reset --soft" is "...but leave the working directory alone".

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton