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

推荐订阅源

Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 【当耐特】
阮一峰的网络日志
阮一峰的网络日志
S
Secure Thoughts
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tenable Blog
T
Tailwind CSS Blog
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
Webroot Blog
Webroot Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
The Cloudflare Blog
T
Threat Research - Cisco Blogs
V
Visual Studio Blog
Jina AI
Jina AI
V
V2EX
I
InfoQ
Latest news
Latest news
P
Proofpoint News Feed
T
Threatpost
Engineering at Meta
Engineering at Meta
P
Proofpoint News Feed
美团技术团队
The Register - Security
The Register - Security
L
LangChain Blog
Apple Machine Learning Research
Apple Machine Learning Research
aimingoo的专栏
aimingoo的专栏
GbyAI
GbyAI
Cloudbric
Cloudbric
Microsoft Azure Blog
Microsoft Azure Blog
C
Cisco Blogs
U
Unit 42
Microsoft Security Blog
Microsoft Security Blog
MyScale Blog
MyScale Blog
V
Vulnerabilities – Threatpost
TaoSecurity Blog
TaoSecurity Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Recent Commits to openclaw:main
Recent Commits to openclaw:main
W
WeLiveSecurity
博客园 - 司徒正美
T
The Exploit Database - CXSecurity.com
小众软件
小众软件
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园_首页
N
News and Events Feed by Topic

Lobsters

CIFSwitch: a non-universal Linux local root vulnerability RIPE NCC session fixation: poaching logins with an Atlas probe GNOME 2.20 but its Web Components Agentic Search for Context Engineering – Leonie Monigatti Garnix is shutting down [not OC] akashina.tngl.sh/jjc Concerning Emacs (and Jazz) Nitpicking the shell history scene in ‘Tron: Legacy’ What's cooking on SourceHut? Q2 2026 The tenth OpenPGP email summit Package managers that package package managers Clojure on Fennel part three: parsing WordPress at 23 Finding Miscompiles for Fun, Not Profit GitHub - creusot-rs/creusot: Creusot helps you prove your Rust code is correct. Announcing Rust 1.96.0 | Rust Blog A Love Letter to Neovim sqlite AGENTS.md Am I a Bad Friend? CSS vs. JavaScript • Josh W. Comeau Erlang Ecosystem Foundation - Supporting the BEAM community A brief note about slot access cost in Common Lisp Keyboard latency probe Rethinking the GNOME clipboard issues Back to the Building Blocks’ Building Blocks Tech Notes: Theseus: translating win32 to wasm Fast is better than slow Content-addressed Rust builds (or, what kache actually caches) Intent to Prototype: Embedding API Canada’s Bill C-22 and the security cost of collecting more data 5 PostgreSQL locking behaviors that trip people up okmij.org Stop advertising in your commits! | AksDev GitHub - mplsllc/macsurf: A modern web browser for Classic Mac OS 9 PowerPC. Real CSS3, ES5 JavaScript, native HTTPS — built with CodeWarrior on the Carbon API. Introducing DoomBench - Can Your Data Stack Run DOOM? What are some of your favourite developer tools? Building a Scalable Ingestion Pipeline with Temporal (Part 1) Converting shallow Git bundles into normal repositories Are you a member of any professional associations? What is a harmonic? An interactive comic about additive synthesis How Virtual Tables Work in the Itanium C++ ABI Using SwiftUI to Build a Mac-assed App in 2026 Rust (and Slint) on a jailbroken Kindle. ~jack/lambda-on-lambda - Serverless Haskell on AWS - sourcehut git Human proof for FOSS contributions Extremely simple internet radio controlled via IRC Announcing BABLR Splitting Konsole views from Helix to run tools | AksDev GitHub - yugr/rust-slides Serving files over HTTP three ways: synchronous, epoll, and io_uring update docs with information about building with build.py (#979) · astral-sh/python-build-standalone@c9c40c5 A Simple Makefile Tutorial On C extensions, portability, and alternative compilers Switching to Colemak | Pedro Alves Just How Bad Was The Intel IAPX432? Nix's Substituter List Is Not a Routing Table Accelerating copy_if using SIMD Lambda on Lambda: Serverless Haskell on AWS | Blog Announcing feed-repeat v1.0 Scaling Akvorado BMP RIB with sharding EYG news: A host of CLI improvements, new guides and new effects The social contract of writing JS Crossword C array types are weird; and related topics Flatpak will depend on systemd – OSnews Migrating from Go to Rust | corrode Rust Consulting A portentous reunion Vivado Licensing Options How my minimal, memory-safe Go rsync steers clear of vulnerabilities the entropy layer of a wavelet codec, on its own GitHub - nferhat/fht-compositor: A dynamic tiling Wayland compositor. Debian SE Linux and PinTheft Does bulk memmove speed up std::remove_if? (No.) 声明式部分更新 | Blog | Chrome for Developers Fully in-browser container builds Dianne Skoll's Web Site - Remind The Architecture of Open Source Applications (Volume 1)Berkeley DB Pardon MIE? - ironPeak Blog “Long-Term Support” doesn’t mean what you think Jira IS Turing-Complete May I recommend thinking of Emacs as your Fortress of Solitude hershey Floodgap Gopher-HTTP gateway gopher://thelambdalab.xyz/1cuneiforth/ HP QuickWeb, Singular And Pointless That one time I used Go panics for flow control A new suite of modern tools coming for editing and publishing RFCs From the Tabletop… The Digital Antiquarian Building a Host-Tuned GCC to Make GCC Compile Faster Are we self-sovereign PKI yet? Claw Patrol: an open-source security firewall for agents | Deno Revised^7 Report on Scheme, Large: Procedural Fascicle Draft is now public A Network Allow-List Won't Stop Exfiltration — André Graf From AFSK to Goertzel – µArt.cz Software For My New Home Server Introducing Neptune: Direct3D virtualization for QEMU AI Agent Bankrupted Their Operator While Trying to Scan DN42 - Lan Tian @ Blog mimalloc: A new, high-performance, scalable memory allocator for the modern era Making wl_shm fast The Soul of Maintaining a New Machine - Third Draft | Books in Progress What is Git made of?
Towards Understandable Software
Anna Liberty · 2026-06-28 · via Lobsters

Why programming sucks and how to fix it

2026-03-07 · 13 min · #computing

Programming sucks. Code sucks. It's hard to read, hard to test, and hard to maintain. Only a handful of people can understand any particular software project. These are major problems. I'm here to explain how we can fix them.

LLMs aren't the Model

Large Language Models (LLMs) are becoming an important part of industry software development. Even experts with years of experience are using LLM agents to test, debug, and even write code. Now that many LLMs are capable of integrating with their environments, some of their logistical problems have been mitigated.

Non-programmers have also turned to LLMs. Programming can be unapproachable. Many people have no clue where to start and, even if they did, have no desire to learn the fine details of the syntax and libraries of any particular language. I regularly see people with little programming knowledge use LLMs to write them anything from simple personal scripts to tools for processing scientific data.

I don't believe this is the result of LLMs being incredible at programming. Almost everyone in the field has seen the results of a session of vibecoding. Even if the tests pass, the resulting code is usually atrocious.

No, I believe programmers and non-programmers alike have turned to LLMs because programming sucks. There are so many conflicting software stacks, endless boilerplate, and annoying libraries. The work of the average software developer has been reduced to gluing libraries together rather than developing interesting code.

But the fact that programming sucks doesn't make LLMs suck any less. The major problems with them persist. They still are environmentally destructive, fundamentally based on stolen code, produce inconsistent code, and instill dependency. Overall, LLMs make programming worse than it has been before, despite their promise. We deserve better than current programming paradigms, but we also deserve better than LLMs.

We Can do Better

We don't have to give up automation if we give up LLMs. We don't have to give up high levels of abstraction if we give up LLMs. We don't have to give up human-friendly interfaces if we give up LLMs.

The benefits promised by LLMs may not outweigh their costs, but we don't have to give up those benefits. We can have predictable, high-level, testable systems that make software more maintainable. We don't even have to give up using natural language to communicate with machines. We just have to take a different approach.

Instead of tackling the problem of writing code, we should tackle the software stack underlying the code. Instead of making it easier to generate endless amounts of code, we should eliminate the need to write it at all. We should embrace the layers of abstraction that have led us to higher and higher level languages. When the urge to automate one layer of abstraction emerges, we should instead abstract it away.

The prevalence of LLMs in programming has shown us we need a different approach to programming. The urge to automate the process of writing code has shown us we need to abstract the need to write code at all. We need another layer of abstraction that allows us to think about software even to the ways humans—not computers—naturally think.

Document the Yak

The first and most important step of making software understandable is documentation. If we want software to be understandable to other humans, the least we can do is explain it to them.

Programmers already know that documentation is important, but for the most part we see it as something to tack onto the code afterward. We write the code, and then maybe add doc-comments to explain what outwardly facing functions do. If our users are lucky, we'll even write usage examples.

I propose we flip this. Instead of writing the code first and tacking on documentation, we write the documentation first and tack on the code. We tell humans what our program does and then we tell the computer what it is supposed to do. This is a concept known as Literate Programming.

Imagine this: instead of reading other people's code and then trying to parse their intentions form it, you read the documentation to understand their intentions and then you read the code. You no longer have to strain yourself trying to understand what someone wrote for another audience (the machine). They've already explained it for you.

The best implementation of this I'm aware of is the Entangled bi-directional tangler. A tangler extracts code from your documentation and distributes it across the appropriate source code files. It's bidirectionality means you can use it to write code embedded in documentation, but then also edit that code normally which it then propagates back into the code blocks in the documentation. This allows programmers to use existing tooling for testing, refactoring, and code formatting without special support for literate programming.

And it's fast. Tanglers add little overhead to your build system, especially compared to a compiler.

We should embrace this approach and document the entirety of our software stack, from the firmware that boots our computers to the Web applications we use to connect with our communities. This would make every aspect of software more accessible to those who use and develop it.

Go ahead and shave the yak, but also document it.

This approach doesn't directly solve the ways that programming sucks. It still involves code and all the messiness that entails, but it makes that sucky code more comprehensible. It replaces LLMs in one area: understanding other people's code.

Abolish Code

But we can go further. Not only can we document our code—we can destroy it.

Code is a concept from a bygone era. We were forced to work with it because we used to interact with computers through terminals. We used a keyboard to input instructions into a computer, which then ran interpreted and ran those instructions.

There's no reason we have to keep this approach. Insisting we communicate with our computers with barely more than a one-dimensional series of obscure symbols and keywords is a refusal to take advantage of how computing has changed over the last 40 years.

Embrace structure. Abolish code.

Embrace the GUI

I believe one important aspect to replacing code is embracing the Graphical User Interface (GUI). Most of us don't interact with our computers solely through text-based interfaces anymore. There's a good reason for that! GUIs allow us to reason about concepts in more complex ways than text-based interfaces while also often being more approachable to new users.

We can do the same for creating software. Integrated Development Environments (IDEs) can be more than just places to conveniently edit code. They can become fundamentally new ways of interacting with software development. Many IDEs already provide some of these features. We should go further.

Visual programming should become so ubiquitous and simple that anyone could create whatever they want without having to learn any code. I want to live in that future.

We don't even have to give up code! The GUI version of a program could merely be one of several human-editable representations. Just as some people love text-based interfaces to their operating systems, some people will continue to enjoy code-based interfaces to software editing. It just doesn't have to be the default—or the only—option anymore.

One important thing to touch on is accessibility. While this kind of visual programming is specifically designed to be more accessible, embracing a visual environment for software development can exclude people with vision impairment. I want to emphasize the importance of ensuring that, visual programming is always just as accessible to those who can't see it. This can take the form of strong screenreader integration, or even an alternative representation specifically designed to be just as richly understood audibly or tacitly.

Code is Cheap. Show me the Talk.

I've observed several people talking about how LLMs move the level of abstraction up one more level. They talk about how LLMs are what allows humans to interact with computers using natural language, and that we are approaching an age where human-written code will be a niche activity like writing assembly is now.

I don't believe this is the case. In my opinion, LLMs do not represent a layer of abstraction, but rather a layer of automation. It doesn't abstract away the code layer, it automates it.

In say this because layers of abstraction are meant to be predictable and reliable. The intentions at a higher level of abstraction are supposed to be represented accurately and consistently at lower levels of abstraction. This is not the case with LLMs. Instead, LLMs stochastically interpret their prompts and predict intentions. They behave unpredictably. They automate the process of randomly approximating the output of a task. If LLMs are a layer of abstraction, they're an incredibly lossy one at best.

Still, Torvalds's quote can still be inverted. Instead of thinking about code, we can think about "talk". Because what if "talk" and "code" weren't different at all?

Humans have evolved a vast diversity of languages over the span of our existence. Our individual languages represent rich histories and are well-adapted for expression between humans. While optimized for interpersonal communication, they're not optimized for predictable communication with machines. That's why we've used code for this purpose so far. However, recent advances of Natural Language Processing (NLP) may be just what we need to create predictable pipelines from natural language to machine code.

This approach may not be able to express the same logical relationships as clearly as visual programming, but it's an approach that may be even more accessible to non-programmers. Imagine being able to type instructions much like you might into an LLM prompt and create complete programs, but ones that are predictable and robust every time. Ones that build directly on other people's work through definitions, rather than ones that are merely distilled averages of code used without their author's intent.

This could even allow us to merge documentation and code even further. We can literate programming and replace the code with natural language until only documentation remains. The same writing we use to talk to other humans about how the program works could be the same writing we use to communicate with the machine.

This is meant to be deterministic. NLP can be used to parse semantics from the grammar without the generative capacity of transformer models. That parsed grammar can be translated directly into an intermediate that is compiled according to platform requirements, just like any other programming language.

Something like Inform but with more syntactical awareness and connected to a broader network of definitions.

This deterministic quality means prompts become code reliably and consistently. This is fundamentally different than any LLM. It's a true layer of abstraction.

We've Done This Before

None of these ideas are new. There have been previous attempts to implement them. The best example I'm aware of is Eve, a programming language and IDE meant to make programming more accessible to humans.

To do this, Eve takes a literate programming approach. They embed their domain specific data-oriented programming language in documentation that describes how the software behaves to other humans. The code is subservient to the documentation and the entire programming environment reflects it.

They explored this idea further, even trying to replace their custom language with NLP querying. Unfortunately, processing natural language comes with complexities they were not compared to handle. They did not have the resources to turn it into a reality. In 2016 more advanced forms of NLP weren't as accessible to companies that weren't focused on Machine Learning. They even experimented with a GUI-oriented approach!

A former Eve contributor also talks about some of the complexities of the project. Their post also expresses some of the same concerns about the limitations of LLMs I do here.

Unfortunately, the project was ended largely because it was an ambitious VC-funded project that failed to monetize their product, so we never had the opportunity to see their ideas come to fruition. I believe it could replicated and expanded with a better financial model.

This has also been done extensively by Inform, which is a declarative language for creating interactive fiction, but the concept can be applied much more broadly.

It's possible natural language is fundamentally a leaky abstraction. But I believe it's worth another shot. The potential unlocked by giving the average person direct control over their computers deserves much greater attention. It deserves more attention than we're giving it. It deserves better than LLMs.

Bringing it Together

Programming sucks. But that doesn't mean we should automate it away and have LLMs write everything for us. Instead, we should abstract code away, building on top of it to provide robust and deterministic systems that allow us to describe software at a higher level.

We should embrace visual, literate, and natural language programming in order to better communicate our intentions with machines and with each other. We should follow in the steps of projects like Eve and create programming environments that focus on expressing complex ideas to other human beings rather than machines. Every form of software at every level of the software stack should become accessible to programmers and non-programmers alike.

This world is possible. This world is necessary. We just need to build it.

Next Steps

I believe in the importance of making understandable software. To this end, I'm working on projects that further this goal.

Primarily, I develop ReTangled, an Entangled-compatible bi-directional tangler written in Rust. It's meant to extend literate programming as far as it can go while integrating it as tightly into existing toolchains as reasonable. As of writing, it's in the early stages of development. I welcome contributions!

And for each of the different ideas I explore lightly here (visual, literate, and natural language programming), I am going to write more completely on each and thoroughly elucidate their potentials going forward.

Further than that, though, I want to explore more of the problem space as a community. Specifically, I want us to pick up in Eve's footsteps, maybe taking a slightly different approach. I want us to create a highly-documented and accessible visual or natural language programming environment that anyone from new to expert programmers can find useful. That vision, while distant, is a worthy goal.

So please, join me! Let's start by better documenting our software and end with upending the very concept of programming.