94,477 karma · joined October 13, 2008
jerf@jerf.org , though be aware that I only really check email every few days now.
Permission for comment republication in HN collections granted, though please do drop a line to jerf@jerf.org so I know. :)
my public key: https://keybase.io/jerf; my proof: https://keybase.io/jerf/sigs/vL9FeVDSGtiDMBmXC4f_rCikI0n4jNfB-1PsNgUN-Is
By default, if you ask an AI to "generate documentation for this code" it generates the same broken documentation all the humans do too; an enumeration of all the modules in the code and what their API is. I'm not surprised, the training data is biased probably at least 25:1 in favor of this rather than the useful data flow documentation. Fred Brooks was complaining about this over 50 years ago and the discipline as a whole still gets this wrong.
I'm not saying this is a future solution to all problems, but it is a now solution to some problems.
3D doesn't help. We live in a 3D world but our vision is 2D with a bit of augmentation from a second view point just a bit away. We derive some depth information from that, but we don't really "see in 3D". To do that we'd need to be 4D beings. There's a lot less juice in the 3D squeeze than meets the eye.
I kind of want to leave it there. But that will probably be looked on disfavorably.
I've seen at least a dozen attempts. It's not like it's hard to write it out. There's maybe a couple of variants but they're all just a handful of lines. The problem is, once you have an Option in hand, you end up trading:
val, err := whatever(...)
if err != nil {
// handle error
}
// use val
for val := whatever(...)
if err, isErr := val.Error(); isErr {
// handle error
}
realVal := val.Value()
// use realVal
What you win in nominal safety, you're definitely losing in convenience.There's also no win in trying to offer a monadic interface like
finalVal := whatever(...).OnVal(func (val Value) opt.Option[Result] {
// use val
})
because that's the minimal specification of an anonymous function in Go, so it's very inconvenient. Even if that was trimmed down, nested functions are still problematic in other ways. And you still have to unpack finalVal anyhow.Really the solution is, install golangci-lint, turn on errcheck [1], use a pre-commit hook to make it a commit failure if golangci-lint fires, and that pretty much covers the problem in practice.
One of the problems with Option/Result/etc. advocacy... not the pattern itself, the advocacy... is that it is generally are presented, implicitly or explicitly, as if the alternative is C, with its errno and the need to not just check an error value, but remember to go actively seeking out errors constantly, making it easy to forget. But by modern standards, that's completely pathological.
If we rate error handling techniques on a scale from 1 to 10 (best), C here is a 1, and standard Option is maybe an 8 or a 9. The way Go does it is maybe a 6; it is completely true that you can neglect to handle an error (see errcheck comment in previous paragraph), but it is in your face that an error is possible, and that's really most of the problem. Putting Option/Result/etc. is not always a "go from 1 to 9" result. "Go from 6 to 8" is a much less impressive proposition, and the other inconveniences that come with it in Go tend to overwhelm the gain. I use errcheck all the time, and even in the Before Times when I was writing it all by hand it really didn't fire all that often. Especially if I exclude test code. In an AI era this hardly rates at all. AI never neglects the error.
Whether it does the right thing with it, now... that's another story entirely.
Read those error handling clauses if you're writing Go with AI. I really don't like what I've seen AIs do with them by default. What I've seen out of AI has been very thoughtless. Nominally correct in some weak sense, but thoughtless.
[1]: https://golangci-lint.run/docs/linters/configuration/#errche...
Turning things into big piles of numbers isn't what takes them from you. It's the hardware and ecosystem that limits what you can do with the numbers. The reason Amazon could delete that book isn't that the numbers were particularly deletable somehow, it's that people were using systems that let someone else control them.
The other problem with this sort of benchmark, which is a mistake I also commonly see made by Node developers, is that the Ruby HTTP stack has significant native code in it, like: https://github.com/puma/puma/tree/main/ext/puma_http11 This is a good and proper thing that brings benefits to all involved; it's not like it's "cheating" or anything, it's a real performance benefit. But it does mean when you're benchmarking a simple HTTP server, you're benchmarking Ruby qua Ruby a lot less than you think you are, and so the relevance of such benchmarks to codebases that have actual Ruby in them will be less.
[1]: https://programming-language-benchmarks.vercel.app/python-vs...
If it is the case that the original machine has an intermittent hardware fault, that analysis is exactly what I'd expect of an current AI. Voluminous and confidently wrong. Also interesting that the AI itself doesn't note this... having been biased by the conversation to consider kernel bugs, in the "cross-machine data" [1] it blames the kernel and doesn't appear to consider alternate explanations.
It doesn't get mentioned much around here but one major issue with AIs today is that they fall into tunnel vision very easily and often need some help getting out of it. There's a structural reason for tunnel vision built into their context limits, and there's also situations like this, where if you bias them in a certain direction they can get monomaniacally stuck on it. You can also see it where they do things like try to do something on your system like view a certain file, then if for some reason they fail due to permission issues, if you don't stop them they'll go absolutely insane trying different ways to access the file, rather than just stopping and saying "Hey, I need help". Even if you prompt them directly to do that, it only helps, it doesn't fix the issue. I suspect the RHLF training they get to be better coding agents reinforces this behavior because in the coding quality tests they're rewarded for one-shotting all the various benchmarks, where that "bull in a china shop" approach works better than giving up. But I'd actually like them to give up a bit more often. I've had the same problem with some particularly go-getting junior devs, too... I appreciate the ambition and I look forward to harnessing it in other situations but I'd rather you didn't spend five hours to create a terrible work around to something I could have gotten you in two minutes. For the junior dev, it's OK, they take the feedback and adjust... the AIs never adjust.
[1]: https://github.com/dfoxfranke/ripgrep-3494-analysis#6-cross-...
Anyone moaning about how it's ruined Go is either not using Go, or simply impossible to please.
If you hate Go... and hey, you do you, I've got my own list of languages I don't like... find a better complaint because this one is simply nonsensical. "It doesn't let me map/filter/reduce" or "it doesn't fix lock problems" or other similar complaints have some grounding in reality, but this one is just absurd. Generics aren't used enough to be "the worst thing ever". Fears about how Go would instantly turn into a language full of generics that take generic arguments that take generic arguments have proved to be wrong.
"Non-commercial" use can relate to one particular aspect of fair use, but there definitely is no blanket "you can copy work for non-commercial use" proviso in copyright law.
It fell off the front page but here's a relevant story from today: https://news.ycombinator.com/item?id=49123300
What more is America supposed to do to remove this individual freedom from people? There is no bigger stick than the law.
Americas have had no problem with blue laws historically [1], which are laws about what can be done on Sunday largely connected to religious observations, as well as laws on "vice" and entire vice police [2] organizations.
It is no contradiction of individualism, and arguably a strong expression of it, to ensure that anything that can diminish individualism or directly attacks it also needs to be regulated. Heavy drugs, gambling, loot boxes, there's a whole variety of things that humanity has learned the hard way have a tendency to enslave those who indulge in them, and legally banning or constraining those things is perfectly in line with a philosophy of legal empowerment of the individual.
We also have a loooot of ways that people having problems with addictions can reach out for help. There is some truth to the idea that we have moved in the direction of being less willing to force that help on people, and some criticisms to be made there, but then, there were historically reasons for that shift as well that need to be incorporated into any holistic opinion of the situation.
[1]: https://en.wikipedia.org/wiki/Blue_law
[2]: https://thelegalguide.org/what-is-vice-police-what-is-their-...
Whether it is simulating emotion or feeling it isn't relevant in this case, because the problem is that it affects the output.
I agree, but the problem I see far more often is the people who claim something is "fair use" without considering any of those four criteria, for which the four-question analysis returns a clear "no" for all four questions. Or "unclear but trending no".
The internet at large defines "fair use" as "I want to be able to do that for free".
Yeah, maybe somewhere in the bowels of the megabytes of legal proceedings there's some fair use case that clearly failed all four criteria and was still found to be "fair use". This being 2026, I went ahead and asked an AI if it could turn up such a case, with the "high effort" on, and it came back with no. My prompt specified that I wasn't looking for the judge to rigidly specify "no", just express a belief that they were weak but then rule in their favor anyhow. Maybe an AI oriented towards legal searching could do better and if someone can come up with one, I'd be interested in seeing it.
But even if someone does come up with one, it is fairly clearly a curiosity and not something you should bet your future legal status or a business on.
However, LLMs are fantastic at it. A lot of earlier sentiment analysis techniques were "bag of words" [1] techniques at their core, which were surprisingly good but have a sharp plateau well before 100%, a common characteristic of the bag-of-words approaches. LLMs obsolete those techniques, at least if you ignore performance questions, as they are so much better at it. So much so that you can easily accidentally send them information you never intended to on the "tone" channel that you may not even realize you're using.
So do the AIs. Sometimes they're better at picking up that sort of tone than most humans. And they definitely respond to those things. The fact that an agent can't really "have" a "job" won't matter.
I still get a big win from AI on the net, but you do need to budget some time to clean up. I'm still on team "read every line".
In fact this is a case where I deliberately deferred some review because I was a blocker for another team. Now that I've got something to them I'm going back and I'm going to eat a bigger chunk of debt than I normally would, but it's worth it for unblocking the other team sooner. AI has made tech debt easier to take out, in all senses of that term.
It is also pretty decent, in my experience, at being guided into how to fix tech debt. Some other people's experience varies: https://news.ycombinator.com/item?id=49035455 YMMV.
When thinking about a standard like this, thinking about "your" system is a fatal error. You have to think about all the systems. And, yes, there are systems out there in the world that load large numbers of emails simultaneously. Obviously. Many of them. Not only that, if a new standard can't capture some of those, it's going to be a worthless niche standard forever because those are precisely the nodes that you need to get to support the new standard.
"If we're specifically talking about being able to short-circuit after headers, then why not a JSON header followed by JSON representation of the body?"
Just because a JSON representation of the body is pretty worthless. MIME is an extremely well-known standard, already used in HTTP contexts, and it will be more efficient than JSON string encoding at a fairly small transition size.
I'd also observe that "brute force" here is an O(source * target) problem, where a source/target pair is some expressible command. e.g., you can't usually combine two locations on the screen, but you can try to combine any item with any screen location, and in some games, any item with any item. Some games add a term for "verb" to that as well, though most games nowadays wisely realize that's not really helpful.
You can see the core reason why people complain about "moon logic" isn't really that the logic is weird. I don't think that specifically bothers too many people. Often it's part of the fun in a way. The problem with "moon logic" is that it means I can't cut down on that search space with common sense or clever-but-grounded logic. In reality rubbing my cat with a piece of tape to pull some hair off of it so that I can wear that tape as a fake mustache is not a sensible option to consider, which is a real part of a real puzzle [1], not just something I made up. A game that consider that a solution to a problem is a game I have to rub everything on everything and it is not just "gamers being lazy" that they don't want to perform hundreds or thousands of possible actions, where all but one of them will result in failure, and depending on the game, some of them may even result in "game over". That's terrible design and that's not the player's fault.
[1]: The classic Old Man Murray article, for today's 10,000: https://www.oldmanmurray.com/features/78.html The rest of the puzzle isn't exactly a tour de force of logic either.
On my current fiber provider, I'm already behind a very large CGNAT install. To a large degree, de facto that's already a lot of the "non-sketchy" use cases for VPN covered for me. IP addresses are already one of the weaker signals for tracking people as it is. Mobile networks have been letting you shift IPs for years just by how they work. Other internet providers that don't slap thousands of people at a crack behind one IPv4 with CGNAT didn't necessarily guarantee stable IP addresses, hence the need for dynamic DNS for decades.
The hole VPNs plug is necessary, but not even remotely sufficient if you are trying to actually protect yourself from some attack. Slapping a default Windows 11 install on a VPN to a first approximation protects you from nothing.
And since the "non-sketchy" uses are rather dubious, that really does sort of leave just the sketchy ones. I don't think it's a coincidence that when they pay a YouTuber to advertise them, the YouTuber generally ends up talking vaguely about the protections but fairly concretely about the sketchy uses, with screen shots showing them using Netflix in a different country. The companies know what they're getting used for and what they can provide.
This style of game died for a reason. I'm not saying it needs to stay dead, but I do think every entrant to the genre needs to grapple with those reasons and have an answer to them. The episodic format provided one decent answer, even if I don't necessarily love it as a monetization technique. Adventure games all tend to pass through episode-like gates anyhow because the combinatorial state space becomes overwhelming without them, but they often still carry over state from the previous phases of the game. The full clean-slate wipe of the episodes prevented that from becoming a problem.
Oh, that's not even a challenge. The reason to offer a scheme like this is basically to abuse the fact that a human customer will value this disproportionally to the cost of providing it. But if the customer perceives that value, that means you can take that surplus, which isn't real, and then extract that surplus from almost anything else that comes in the form of real money, and create something that humans value as much as the original service, but now with more money to the service provider. Converting the customer irrationality into money means you don't even need anything as obvious as a cap, which sounds scary. You just raise your other prices.
As a specific example of this, I've been using emacs since about 1997, but it's only this year that I've started down this sort of "integrate everything" road that it promises, because I've never wanted to learn emacs' specific Lisp variant that is used nowhere else. But now with AI I've done more emacs extensions that are providing real value to me than I have in the last... ever. About my previous limit was reifying a keyboard macro into a command, which still isn't really programming emacs.
The ability to indicate "intent" in a way that computers can actually process it as "intent" might change the calculus enough to make this more possible than it used to be in the past.
But those tradeoffs are real. Non-determinism is a problem. Difficulty in knowing what the AI is doing unless you're staring at its output, and even the ability to conceivably monitor an AI's output is only a transient thing we have at the moment, they'll speed up past our ability to monitor them at all soon enough. But it's at least a new area that can be explored and there may be solutions to some problems in there we couldn't reach before.
This looks like a good overview paper for interested folk: https://pmc.ncbi.nlm.nih.gov/articles/PMC3048989/
It's a Chesterton's Oscillating Fence, on a generation time scale.
AIs, at least in their current form, make you more who ever you were. If you want snap, glib answers of dubious accuracy, they'll give them to you, more easily than ever before. If you want to dig back into primary sources and get the original content, they'll do that for you, more easily than ever before.
Can't speak to how the science infrastructure is going to handle them, but if it takes down the peer review system, which I think has been worthless for probably going on two decades and has just given the entire enterprise a false sense of assurance, it'll probably be a net gain in the end. Peer review is a source of more problems then it is solving right now.
However, consider that Go has been in production for 14 years now, and one of its bread-and-butter applications is network servers, which will collectively exercise quite a bit of the memory allocation pattern space, including some pathological aspects of it. You should expect to need to do better than that to really throw it for a loop.
While the theorem proves some such sequence exists, there's no guarantee that the sequences will be easy to describe in some sort of English sentence.
"Taking a step back, Go manages memory by allocating objects of the same size class (an object’s size is rounded up to the nearest size class) within a contiguous chunk (or span in Go terminology) of one or more 8KiB pages. Size-segregated allocation is common in some malloc implementations (like tcmalloc, which Go’s allocator descends from)."
(No passive-aggressive snark about reading the article intended; it's a good question and I really am just pasting it for our convenience.)
You can't get the inability to allocate some large object because there's a spray of small objects in its way, because the small objects don't share space with the large object. The large objects live in their own space, and the fragmented small objects can be efficiently utilized later by putting other small things in the empty space later.
In the 64-bit world, you also don't have to worry about how you arrange things in physical RAM so one size doesn't end up impacting another. You can always allocate some suitably-sized new chunk of ram that's incredibly distant in the virtual address space and let the OS map that back to the real RAM. It may do something more clever than that because there is still 32-bit Go and that trick is less freeing in that scenario, but the principle would still hold. You don't get the inability to allocate a large object by small objects because they don't live in the same place. You might still "run out of RAM" before you've quite literally run out of RAM, but you'll get closer.
And ultimately that's a problem shared by a lot of memory allocation schemes, not particular to GC or Go. For a lot of reasons, it's a good idea not to run resource usages right up to 100% if you can avoid it and you can expect across a wide range of resources types to encounter problems and expect to do a lot of careful work to make it possible to hit truly full utilization if you need it for some reason. Beyond computers, even... it's rarely a good idea to plan on 100% utilization of anything be it physical or electronic.
You don't want to embed the entire email in JSON. Too many parsers past, present, and future tend to want to decode the entire JSON document into memory before doing anything else, and so you'd be forcing entire email documents to be held in memory at scale, which causes you major problems. I'd recommend something more like either a JSON header that defines what parts are in the email, followed by a normal MIME document, which is perfectly normal in HTTP with other things that use the format as well, or having the top level continue to be a MIME document and specify that the first part must be a JSON document containing the headers. JSON replacing the headers is generally something that would be a good idea, though.
That improves the ability of more language environments to be able to handle the email as a stream or in chunks with "normal" libraries and practices. MIME parsers in languages that tend to favor pulling everything into RAM as a string are still more likely to have been forced to face this issue already.