惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Archives - TechRepublic
Security Archives - TechRepublic
P
Privacy & Cybersecurity Law Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
W
WeLiveSecurity
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
L
LINUX DO - 热门话题
C
Cybersecurity and Infrastructure Security Agency CISA
S
Security Affairs
Latest news
Latest news
Security Latest
Security Latest
N
News and Events Feed by Topic
Spread Privacy
Spread Privacy
P
Proofpoint News Feed
T
The Blog of Author Tim Ferriss
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
The Exploit Database - CXSecurity.com
The Last Watchdog
The Last Watchdog
C
Cyber Attacks, Cyber Crime and Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
V
Vulnerabilities – Threatpost
Hacker News - Newest:
Hacker News - Newest: "LLM"
Microsoft Azure Blog
Microsoft Azure Blog
V
Visual Studio Blog
The Cloudflare Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
G
GRAHAM CLULEY
博客园_首页
S
Secure Thoughts
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
AWS News Blog
AWS News Blog
腾讯CDC
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Register - Security
The Register - Security
N
News and Events Feed by Topic
A
Arctic Wolf
MongoDB | Blog
MongoDB | Blog
爱范儿
爱范儿
Project Zero
Project Zero
A
About on SuperTechFans
罗磊的独立博客
云风的 BLOG
云风的 BLOG
Know Your Adversary
Know Your Adversary
S
Security @ Cisco Blogs
Google Online Security Blog
Google Online Security Blog
K
Kaspersky official blog
L
LINUX DO - 最新话题
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
F
Fortinet All Blogs

Ben Hoyt's technical writing

Every dependency you add is a supply chain attack waiting to happen Don't fear Python subprocess or Go codegen Go performance from version 1.0 to 1.22 The One Billion Row Challenge in Go: from 1m45s to 3.4s in nine solutions Switching from S3 to Tigris on Fly.io Discussing Forth, C, CGI, Python, Go, and AWK on "Stray Pointers" "Stray Pointers" interview Using a Markov chain to generate readable nonsense with 20 lines of Python How (not) to apply for a software job The AWK book's 60-line version of Make Using the WordStar diamond in 2023 Name before type: why 'age int' is better than 'int age' The proposal to enhance Go's HTTP router Scripting with Go: a 400-line Git client that can create a repo and push itself to GitHub Names should be as short as possible while still being clear Lookup Tables (Forth Dimensions XIX.3) For Python packages, file structure != API Designing Pythonic library APIs From Go on EC2 to Fly.io: +fun, −$9/mo Code coverage for your AWK programs I/O is no longer the bottleneck microPledge: our startup that (we wish) competed with Kickstarter Rob Pike's simple C regex matcher in Go Tools I use to build my website Modernizing AWK, a 45-year old language, by adding CSV support Prig: like AWK, but uses Go for "scripting" Go performance from version 1.2 to 1.18 Optimizing GoAWK with a bytecode compiler and virtual machine AWKGo, an AWK-to-Go compiler Improving the code from the official Go RESTful API tutorial Simple Lists: a tiny to-do list app written the old-school way (server-side Go, no JS) Structural pattern matching in Python 3.10 Mugo, a toy compiler for a subset of Go that can compile itself How to implement a hash table (in C) Performance comparison: counting words in Python, Go, C++, C, AWK, Forth, and Rust The small web is beautiful Coming in Go 1.16: ReadDir and DirEntry Fuzzing in Go Searching code with Sourcegraph Different approaches to HTTP routing in Go Go filesystems and file embedding The sad, slow-motion death of Do Not Track What's new in Lua 5.4 Hugo: a static-site generator Generics for Go More alternatives to Google Analytics Lightweight Google Analytics alternatives An intro to Go for non-Go developers ZZT in Go (using a Pascal-to-Go converter) Testing in Go: philosophy and tools The state of the AWK What's coming in Go 1.15 Don't try to sanitize input. Escape output. SEO for Software Engineers
Fun with an indecisive AI coding agent
Ben Hoyt · 2026-06-15 · via Ben Hoyt's technical writing

April 2026

I’ve been having moderate success using an AI agent to help me fix non-trival bugs in GoAWK. But it’s sometimes very indecisive (Mitchell Hashimoto noted this in a tweet just the other day).

I asked it the following question (I’m using Claude’s Opus 4.6 with the GitHub Copilot plugin in the GoLand IDE):

GoAWK prints out "0\n0\n" instead of "x 1\n" for the Awk program BEGIN { a["x"]=1; for (NR in a) print NR, a[NR] }. Why?

It diagnosed the problem within a few paragraphs, and quicker than I could. It showed that I’m storing these special variables as native Go ints, which lose any string representation.

Then it started trying to fix it. Over the course of several minutes, with me becoming more and more amused, it gave me 7 unique options for fixing the bug, and flip-flopped between them no less than 25 times.

Here are the options it came up:

  • Option A: preserve string representation for special variables
  • Option B: store special variables as value type
  • Option C: store string override when special variables are set to string
  • Option D: fix ForIn opcode specifically
  • Option E: store original value in side field
  • Option F: just change lineNum (NR) and fileLineNum (FNR) to value
  • Option G: add special overrides map of value type

Every few seconds it would say “Actually, the simplest fix…” or “But no, the real issue is…”. It went on and on until I cancelled it.

To its credit, it proposed Option B most often (11 out of 26 times), and that’s almost certainly the proper fix. I’ve done it in this PR.

For your interest, I’m including a version of the chat output below. It’s heavily clipped to just show when it was suggesting another option. I’ve marked those in bold, like this: Option A.


Looking at this bug, the issue is in the ForIn opcode handler…

But wait, let me look more carefully at the actual ForIn implementation …

Now I can see the bug clearly …

This confirms the bug. Here’s the complete picture: …

The root cause is that special variables like NR, NF, FNR, etc. are stored as native Go int types, which inherently lose the string representation. …

The fix needs to happen in setSpecial and getSpecial — we need to preserve the string representation for these numeric specials. … Option A

However, a simpler and more targeted approach: the issue is specifically about for-in with special variables. But really the same problem would occur with any assignment like NR = “x” — it would lose the string. Let me think about the best fix.

The cleanest fix is to store these special variables as value types … but that’s a large refactor. Option B

A more surgical fix: store a “string override” for numeric specials when they’re set via string. But that’s hacky. Option C

Actually, let me think about this differently. …

The right fix is to store the value as a value type and only extract the int when needed internally. … Option B

Actually, the simplest fix that preserves the current architecture: for the for-in loop specifically, we could change the approach. Option D

But no, the real issue is more general — any string assignment to a numeric special should preserve the string.

Let me think about a minimal but correct fix. The most targeted approach: change the numeric special variable storage from int to value, and update the few places that read/write them. … Option B

This is a bigger refactor than I want to do. Let me think of a simpler approach. …

Actually, the most pragmatic and minimal fix is to handle this at the ForIn level. … Option D

Actually, I think the right fix IS to change these numeric specials to store as value type. … Option B

Changing all of these is risky. Let me think of an even simpler approach.

Actually, the simplest correct fix: In setSpecial, for the numeric specials, store the original value in a side field so that getSpecial can return it when it matches. … Option E

OK, let me think about this more carefully. …

This is getting complex. Let me take a simpler approach: just change lineNum and fileLineNum to value type, since those are the most likely targets of for-in. … Option F

Wait, there’s actually a much simpler approach. …

OK let me take the pragmatic approach. The cleanest minimal fix for this specific bug: change the numeric special variables (lineNum, fileLineNum, matchLength, matchStart, argc, numFields) to be stored as value types. … Option B

Actually wait, numFields is heavily used internally as an int. Let me try a different approach. …

Actually, here’s the simplest correct approach: For each numeric special variable, store BOTH the int (for internal use) AND a value (for the AWK-level representation). … Option E

But that’s still a lot of changes. Let me think even simpler…

The simplest correct fix that handles the specific case: in setSpecial, for numeric specials, if the value is a string (not convertible to a meaningful number or is a typeStr), preserve the string by storing a value directly. … Option B

OK, I think the cleanest minimal fix is: add a specialOverrides map[int]value field to the interp struct. … Option G

Actually wait - that’s overcomplicating it. Let me re-examine the specific case. …

Let me just go ahead and do the proper fix. I’ll change the numeric specials to store value types instead of int. … Option B

Let me take a different, much simpler approach. I’ll just make setSpecial and getSpecial properly handle values by adding a specialValues map … Option G

Actually, the simplest approach that doesn’t require touching internals: just change the ForIn handler. … But the problem is getSpecial always reconstructs from int…

OK, let me just do the proper fix. I’ll use a “special values override” map approach: … Option G

OK actually let me reconsider the approach. … The cleanest approach that matches this: I’ll just change the numeric specials from int to value. … Option B

Wait, actually, let me just be even more pragmatic. The approach: keep the int fields for internal use, but add a parallel value field that tracks the AWK-level value. … Option E

Actually no, that’s double-bookkeeping. Let me just bite the bullet and change the relevant fields to value type. … Option B

Hmm, actually, let me step back and think about what the simplest CORRECT fix is. The most minimal fix: only handle the for-in case. … Option D

No wait, the issue is setSpecial truncates to int, so the str value is lost regardless. OK here’s my plan. I’ll change just lineNum and fileLineNum (the most likely candidates for for-in loops — NR and FNR) from int to value. … Option F

Actually, let me just do ALL of them properly. Here’s my plan: … Option B

Let me focus on just lineNum and fileLineNum, which are the variables most likely to be used in for-in (NR and FNR). Option F

Actually, the user’s bug report is specifically about NR. Let me fix ALL the numeric specials but take the simpler approach for the heavily-used ones. Option B (more or less)

Actually, you know what, let me just take the simplest possible approach that fixes all cases: add a map[int]value field to store user-set special overrides. … Option G

Interesting! There’s already a specialOverrides field and delete calls on it. These existed before my changes. …


Now it started to get very confused. It had edited the code to add a specialOverrides map, but then forgot that it had done so. At this point, I just cancelled it.

There are 19 “Actually”s. These are amazing machines, but I’d hate to have a friend who was this indecisive!

More generally, I’d be interested to know how large language models and agents know when to stop. It’s not surprising to me that a token predictor keeps predicting tokens…