HN user

neild

1,242 karma
Posts2
Comments165
View on HN

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.

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!)

AirPods Max 2 4 months ago

Sounds ridiculous, but worked on mine! So far, the fix has stuck, too.

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.

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.

Go's Sweet 16 8 months ago

0600 and 0_600 are octal literals:

    octal_lit      = "0" [ "o" | "O" ] [ "_" ] octal_digits .

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.

Go 1.25 Release Notes 11 months 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.

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).

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.)

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.

Oh Shit, Git? 2 years 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".

I do almost all my cooking on cast iron—no philosophical reason, it just works well and once I figured out how to use it I found that I pretty much always reach for a cast iron pan over stainless steel or non-stick. (Except non-stick for omelettes and stainless steel for anything where I want the find.)

My big realization was that there’s a lot of macho information there about the care of cast iron, and it’s pretty much all pointless because the stuff is indestructible and the seasoning doesn’t matter much. Every time I make tortillas in a pan the seasoning gets wrecked, and it’s just not a problem. So long as you get the pan to the right temp and have enough fat, nothing sticks regardless of the quality of the seasoning. Skimp on the oil or set the temp too low, and stuff sticks no matter how good the seasoning.

I wash the pans with soap and water (and not too much scrubbing), I never season them deliberately, and they work wonderfully. It’s a very forgiving cooking surface.

Returning a channel avoids questions of what happens if sending to a caller-supplied channel blocks. DoChan returns a channel with a single-element buffer, so a single send to the channel will always succeed without blocking, even if the caller has lost interest in the result and discarded the channel.

DoChan doesn't close the channel because there isn't any reason to do so.

There are some interesting results in here, but the slower cases are a bit misleading. The majority of time in the slow cases is spent constructing errors, not in errors.Is.

Some background for anyone not familiar with Go errors:

A Go error is an interface value with an Error method that returns the error's text. A simple error can be constructed with the errors.New function:

  var ErrNotFound = errors.New("not found")
A nil error indicates success, and a non-nil error indicates some other condition. This is the infamous "if err != nil {}" check. Comparing an error to nil is pretty fast, since it's just a single pointer comparison. On my laptop, it's about 0.5ns. Comparing a bool is about 0.3ns, so "err != nil" is quite a bit slower than "!found", but it's really unlikely the 0.2ns is going to be relevant outside of extremely hot loops.

We can also compare an error to some value: "if err == ErrNotFound {}". In this case, we say that ErrNotFound is a "sentinel" (some error value that you compare against). This is about 2.3ns on my laptop; there are two pointer comparisons in this case and a bit more overhead in comparing interface values. (You can actually make this check almost arbitrarily expensive; you could have an error value that's a gigabyte-large array, for example.)

It's common to annotate an error, adding some more useful information to it. For example, we might want our "not found" error to say what was not found:

  return fmt.Errorf("%q: not found", name) // "foo": not found
This is quite a bit more expensive than "return ErrNotFound". The fmt.Errorf function will parse a format string, produce the error text, and make two allocations (one for the error string, one for a small struct that holds it). This is about 84ns on my laptop--168 times slower than the fast path! But 84ns is still pretty fast, and you can't get away from the need for at least one allocation if you want to return an error that's varies based on the inputs of the function that produced it. (You can get faster than fmt.Errorf if it matters, but this comment is already getting large.)

A problem with using fmt.Errorf in this way is that you can't test the error against a sentinel any more. This was addressed a while back in Go 1.13 with the addition of error wrapping. You can return an error that wraps the sentinel (note the %w format verb):

  return fmt.Errorf("%q: %w", name, ErrNotFound) // "foo": not found
And you can then use the errors.Is function to ask whether an error is equal to ErrNotFound, or if it wraps ErrNotFound:
  if errors.Is(err, ErrNotFound) { ... }
On my laptop, producing a wrapping error like this and testing it with "err != nil" is about 91ns, and testing it with "errors.Is(err, ErrNotFound)" is about 98ns. So using Is is adding 7ns of overhead, which is not nothing, but is also pretty much lost in the noise compared to creating the error in the first place.

The example in this blog post went a step further, though, and created an error with not just a single layer of wrapping but one with four. The error text in the wrapped error cases is:

  GetValue couldn't get a value: queryValueStore couldn't get a value: queryDisk couldn't get a value: not found
(That is, by the way, a very difficult error to read. Don't hand users errors that look like that.)

Creating a stack of four wrapped errors like this on my laptop is 396ns, and inspecting it with errors.Is is another 21ns. 21ns is waaaaay more than the 0.5ns for a simple "err != nil" check, but again the runtime here is massively dominated by the expense of creating the error--which in this case involves repeatedly creating formatted strings and throwing them away, and two allocations for each layer in the stack.

In general, when doing low level optimization of Go code, avoiding allocations is the biggest bang for your buck. If microseconds matter, you absolutely should pay attention to the cost of constructing error values. But the cost of inspecting those values doesn't usually become an issue unless nanoseconds count, and will generally be dominated by the cost of construction.

Also, even the slowest cases here are running about 0.5-1.5μs, which absolutely matters in some cases, but is irrelevant in many others.

In addition, Chinese characters encode more information than English letters, so a text written in Chinese will generally consume fewer bytes than the same text in English even when using UTF-8.

(Consider: Horse is five letters, but 馬 is one character. Even at three bytes per character, Chinese wins.)

The article doesn't refer to that incident, so far as I can see. It does mention Patty Hearst, who was kidnapped a year after the Stockholm bank robbery.

The term "Stockholm Syndrome" originates from a police consultant inventing a syndrome to diagnose a woman he had never met, in order to discredit her criticism of the largely incompetent police response to her and several other people being taken hostage by a bank robber.

https://www.independent.co.uk/news/world/americas/stockholm-...

Bluey is the only show my kid loved, and never wanted to binge watch. He’d watch one or two episodes and then want to turn the TV off so we could play Silly Hotel or Keepy Uppy or Grannies. Where other shows grabbed his attention longer, Bluey always inspired him to go out and play.

HTTP/3 is almost indistinguishable from any other protocol running over QUIC, and QUIC itself is almost indistinguishable from random noise in UDP packets. If you want to masquerade as HTTP/3 traffic, just using UDP on port 443 will generally be sufficient.

(Only “almost” indistinguishable, because it’s possible to decrypt the first packets of the client’s handshake and examine the ALPN parameters used to negotiate an application protocol. And QUIC may be further distinguishable from other UDP traffic through statistical analysis of packet sizes and response latencies, as well as the few unencrypted header bits.)

HTTP/3 is not vulnerable to this specific attack (Rapid Reset), because there it has an extra confirmation step before the sender can create a new stream.

HTTP/2 and HTTP/3 both have a limit on the number of simultaneous streams (requests) the sender may create. In HTTP/2, the sender may create a new stream immediately after sending a reset for an existing one. In HTTP/3, the receiver is responsible for extending the stream limit after a stream closes, so there is backpressure limiting how quickly the sender may create streams.

Blemished, non-uniform product is turned into more processed food products or animal feed. Tomato soup isn’t made from the prettiest tomatoes. Blemished apples become applesauce. Tropicana puts a picture of a beautiful orange on the bottle, but they don’t care about what the ones going into the juicer look like. Consumer preferences for nice looking fruits and vegetables have little to no impact on overall food waste.

Grocery store bay leaves are tasteless, at least around where I am. Good ones (I get them from Penney’s) are highly flavorful and add a noticeable flavor to soups and sauces. I even found myself thinking that I’d put too much bay leaf in a pot of beans once, it was threatening to overwhelm the other flavors.

One thing I find fascinating about Lolita is that it is a study in erasure. Society so often tends to erase the victim while giving the abuser a voice, especially when the victim is a child or otherwise powerless and the abuser is powerful and articulate. Lolita gives us a narrative entirely under the control of the abuser and challenges the reader to see through it to the Dolores Haze underneath. Exercising this skill in fiction may encourage us to equally avoid an unquestioning reading of real abusers exculpatory narratives.

Humbert marries Dolores’s mother. After her mother’s death, Humbert travels to Dolores’s summer camp, takes her away, and rapes her in a hotel room. There is no seduction. There is no ambiguity about what happened. She is twelve years old, her mother has just died, and her stepfather has taken her far away from any friends or relatives and had sex with her.

This section of the book then concludes with one of the most chilling passages I have ever read in fiction:

“At the hotel we had separate rooms, but in the middle of the night she came sobbing into mine, and we made it up very gently. You see, she had absolutely nowhere else to go.”

Kubrick is one of those men who looked at Lolita and saw a romance, when it is plainly and clearly a story of appalling abuse and rape. Watching a movie adaptation will not tell you anything at all about the book, because the movies are made by men who did not understand the book in any way.

There are many answers to why Lolita was well received by many people. (It's worth noting that it was certainly not universally well received--many, many people share your opinion of it.)

One is that many of the people who like it seem not to have read it; or if they have read it, they did not understand it. Many men have described it as "a love story" or otherwise indicated that they feel the book approves of pedophilia. Two movies have been made based on the book, and both portray Dolores Haze (the girl the narrator calls "Lolita") as a seductress rather than as a victim. A substantial portion of the fan base of the book are, rather distressingly, men who appear to be quite enamored of the notion of having sex with children.

Another is that Nabokov was a clever writer who excelled at writing books which reward close reading. Lolita is the story of Dolores Haze, but the narrator is a man who has no interest in her other than as than the victim of his sexual attentions. He drones on at great length about trivialities, while completely skipping over vital information. He is deliberately constructing an exculpatory narrative, which opens fascinating questions about how we can find any truth when everything we read is lies. Sifting through his self-serving prose to find glimpses of the actual Dolores Haze is challenging, and--to me at least--interesting.

It's not an easy book, in many senses. The narrator is a monster. The bulk of the story is obscured behind lies and misdirection. There is no catharsis, no happy ending.

Contrary to the opinion of many people who have not read the book, and some who have, Nabokov was extremely well aware that "Humbert Humbert", the narrator, is a monster. Humbert is a pedophile who abducts a 12-year-old girl and rapes her repeatedly over the course of years. Dolores Haze is a victim, not a seductress, and is in no way responsible for or desirous of her abuse. Humbert is not a reliable narrator, and nothing he says can be trusted.

Nabokov himself was a victim of childhood sexual abuse. He knew what he was writing about. There's one scene that is almost certainly directly based on his own personal experience.

I'd have difficulty saying that I enjoyed Lolita, but it's a rewarding book, and I'm glad to have read it.

I have several cast iron pans of varying vintages and styles. They see a lot of use. And my experience is that the quality of the seasoning just doesn't matter that much. If the pan is hot and there's oil in it, almost nothing sticks even if the seasoning is indifferent. The stuff that does stick (tortillas are terrible for leaving carbonized residue on the pan) will do so no matter how good the seasoning is. It doesn't matter, though, because I just scrub it off and the pan still works fine.

Oh, and a bit of dish soap is fine, too. Doesn't seem to bother the pan any.

There's a whole vaguely macho culture around cast iron and the fiddly rituals for producing the perfect surface, but you can just ignore all that and cook on the things and they're fine.