I have successfully vibe-coded features in C. I still don't like C. The agent forgets to free memory latter just like a human would and has to go back and fix it later.
On the other hand, I've enjoyed vibe coding Rust more, because I'm interested in Rust and felt like my understanding approved along they way as I saw what code was produced.
A lot of coding "talent" isn't skill with the language, it's learning all the particularities of the dependencies: The details of the Smithay package in Rust, the complex set of GTK modules or the Wayland protocol implementation.
On a good day, AI can help navigate all that "book knowledge" faster.
There was a recent discussion, “Why AI Needs Hard Rules, Not Vibe Checks” (https://news.ycombinator.com/item?id=46152838). We need as many checks as possible - and ideally ones that come for free (e.g., guaranteed by types, lifetimes, etc.) - which is why Rust might be the language for vibe coding.
Without checks and feedback, LLMs can easily generate unsafe code. So even if they can generate C or Assembly that works, they’re likely to produce code that’s riddled with incorrect edge cases, memory leaks, and so on.
Also, abstraction isn’t only for humans; it’s also for LLMs. Sure, they might benefit from different kinds of abstraction - but that doesn’t mean “oh, just write machine code” is the way to go.
I really tried to get into the vibe coding thing - just describe the thing I need in human language and let the agent figure it out. It was incredible at first. Then I realized that I am spending a lot of time writing clarifications because the agent either forgot or misinterpreted something. Then I realized that I am waiting an awful long time for each agent step to complete just to write another correction or clarification. Then I realized that this constant start-stop process is literally melting my brain and making me unable to do any real work myself. It's basically having the same effect as scrolling any other algorithmic feed. Now I am back to programming myself and only bouncing the boring bits off of ChatGPT.
Why not:
- The C-compiler. AI tools work better if their automated feedback loop via tools includes feedback on correctness, safety, etc. The C compiler is not great at that. It requires a lot of discipline from the programmer. There mostly isn't a compile time safety net.
- Macros add to this mess. C's macros are glorified string replacements.
- Automated tests are another tool that helps improving quality of vibe coded code. While you can of course write tests for C code, the test frameworks are a bit immature and it's hard to write testable code in C due to the lack of abstractions.
- Small mistakes can have catastrophic consequences (crashes, memory overflows)
- A lot of libraries (including the standard library) contain tools with very sharp edges.
- Manual memory management adds a lot of complexity to code bases and the need for more discipline.
- Weak/ambiguous semantics mean that it's harder to reason about code.
There are counter arguments to each of those things. Compilers have flags. There are static code analyzers. And with some discipline, it gets better. You could express that discipline in additional instructions for your agent. And of course people do test C code. There just are a lot of projects where none of that stuff is actively used. Vibe coding on those projects would probably be a lot harder than on a project that uses more structured languages and tools.
All these things make it harder to work with C code for humans; and for AIs. But not impossible of course. AI coding models are getting quite good at coding. Including coding in C.
But it makes it a poor default language for AI coding. The ideal vibe coding language for an AI would be simple, expressive, have great tools and compilers, fast feedback loops, etc. It means the AI has less work to do: shorter/faster feedback loops, less iterations and reasoning to do, less complex problems to solve, less ambiguity, entire categories of bugs that are avoided, etc. Same reasons as to why it is a poor choice for most human programmers to default to.
I very much doubt the ability of LLMs to provide leak-free, faulty memory management free, C code, because they are trained on loads of bad code in that regard. They will not output code of the quality that maybe 1% of C developers could, if even that many. Fact is, that even well paid and professional C/C++ developers introduce memory management issues in such code bases (see Chromium project statistics about this). So chances to get good C programs from LLMs, which learn from far lower quality code than Chromium, are probably very slim.
Vibe-coding a program that segfaults and you don't know why and you keep burning compute on that? Doesn't seem like a great idea.
In loads of projects you can't just pick a language and it's fine.
If I'm making a C#/WPF app, I can't just decide to make part of it C.
I get it's just a generalised criticism of vibe coding, but "why not use a harder language then" doesn't seem to make any sense.
> But if you look carefully, you will notice that it doesn’t struggle with undefined behavior in C. Or with making sure that all memory is properly freed. Or with off-by-one errors.
Doubt. These things have been trained to emulate humans, why wouldn't they make the same mistakes that humans do? (Yes, they don't make spelling errors, but most published essays etc. don't have spelling errors, whereas most published C codebases do have undefined behaviour).
If vibe coding is the future as the author suggests we are in for a lot more and a lot longer outages
> if vibe coding is the future of software development (and it is), then why bother with languages that were designed for people who are not vibe coding? Shouldn’t there be such a thing as a “vibe-oriented programming language?” VOP.
A language designed for vibe coding could certainly be useful, but what that means is the opposite of what the author thinks that means.
The author thinks that such a language wouldn't need to have lots of high-level features and structure, since those are things that exist for human comprehension.
But actually, the opposite is true. If you're designing a language for LLMs, the language should be extremely strict and wordy and inconvenient and verbose. You should have to organize your code in a certain way, and be forced to check every condition, catch every error, consider every edge case, or the code won't compile.
Such a language would aggravate a human, but a machine wouldn't care. And LLMs would benefit from the rigidness, as it would help prevent any confusion or hallucination from causing bugs in the finished software.
>Vibe coding makes me feel dirty in ways that I struggle to articulate precisely. It’s not just that it feels like 'cheating'(though it does). I also think it takes a lot of the fun out of the whole thing.
This exactly. Programming is art, because it comes from the soul. You can tackle a problem a million ways, but there's only one way that YOU would solve it.
Vibe coding feels like people who aren't creative, stealing everyone's creativity, and then morphing it into something they find appealing.
There is no skill.
There is no talent.
You are asking the machine to do ALL THE THINKING. All the little decisions, the quirks, the bugs, the comments to yourself. All the things that make a piece of code unique.
> Or hell, why not do it in x86 assembly?
Because I want to be able to review it, and extend it myself.
edit: Pure vibe coding is a joke or thought exercise, not a goal to aspire to. Do you want to depend on a product that has not been vetted by any human? And if it is your product, do you want the risk of selling it?
I can imagine a future where AI coders and AI QA bots do all the work but we are not there yet. Besides, an expressive language with safety features is good for bots too.
This post mixes up “easy for compilers and assemblers to transform and easy for cpus to execute” with “easy for LLMs to understand” and assumes that anything in the first category must also be in the second category since they’re both computers. In reality, the tools that help humans think are also useful for LLMs.
> Or hell, why not do it in x86 assembly?
It is not portable to computers other than x86. It is one of the reasons I do not use x86 assembly much even though I have a x86 computer; I prefer C. It is not about vibe coding.
> I suppose what I’m getting at, here, is that if vibe coding is the future of software development (and it is), then why bother with languages that were designed for people who are not vibe coding? Shouldn’t there be such a thing as a “vibe-oriented programming language?” VOP. You read it here first.
Someone told me that two companies (one of which is Google) were working on such a thing, although I do not know the details (or if they were correct about that), and I do not know whether or not it resembles what is described in that article.
I do not use LLM myself, although I have seen a few examples of it. I have not seen very many so the sample size is too small, but what I have seen (from simple example programs), the program works although it is not written very well.
Because I don't know C well enough.
My philosophy regarding AI is that you should never have it do something you couldn't do yourself.
Of course people break this rule, or the concept of vibe coding wouldn't exist. But some of us actually get a lot of value from AI without succumbing to it. It just doesn't make sense to me to trust a machine's hallucinations for something like programming code. It fabricates things with such confidence that I can't even imagine how it would go if I didn't already know the topic I had it work on.
I think you should use a language with a highly expressive type system. That can be assembly too. See TAL back from the 1990'es. I also think you should use a language with a very expressive module system.
The reason is that you want to have some kind of guidance from a larger perspective in the long run. And that is exactly what types and module systems provide. The LLM has to create code which actually type checks, and it can use type checking as an important part of verification.
If you push this idea further: use Lean, Agda or Rocq. Let the LLM solve the nitty gritty details of proof, but use the higher-level theorem formation as the vessel for doing great things.
If you ask for a Red-black tree, you get a red-black tree. If you ask for a red-black tree where all the important properties are proven, you don't have to trust the LLM anymore. The proof is the witness of correctness. That idea is extremely powerful, because it means you can suddenly lift software quality by an order of magnitude, without having to trust the LLM at all.
We currently don't do this. I think it's because proving software correctness is just 50x more work, and it moves too slow. But if you could get an amplifier (LLM) to help out, it's possible this becomes more in the feasible area for a lot of software.
Can it generate good code?
Both the author and I agree in that yes, it can.
Does it always generate good code?
Here is where the author and I disagree vehemently. The author implies that the ai-generated code is always correct. My personal experience is that it often isn't. Not even for big projects - for small bugfixes it also misunderstands and hallucinates solutions.
So no C or assembly for me, thank you very much.
If you're going to vibe code, with an intent to review the output so that the ultimate product is actually useful and does what was intended, you should do it in whatever language(s) you're knowledgeable in so you can actually competently review that output.
If you don't give a damn about integrity though, then may as well get funky with it. Hell, go hard: Do it in brainfuck and just let it rip.
> I also think it takes a lot of the fun out of the whole thing.
I used to say that implementation does not matter, tests should be your main focus. Now I treat every bit of code I wrote with my bare hands like a candy, agents have sucked the joy out of building things
I agree that coding is more fun than vibe coding, right up until you have a massive refactor that is super repetitive and no fun to author, but an LLM can do it in no time flat. Even if an IDE can help with the refactor, there are cases where they can't. And anyways, if you're working with a codebase you understand but are not super familiar with, then vibe coding is incredibly productive, though, well, you'll spend much more time reviewing what the LLM did, so maybe not quite that productive (unless you count on others to do your review, but that's not very nice, and it will show).
This is treating the LLM like it is the computer or has some kind of way of thinking. But LLM is a "language" model, I'm pretty sure the easier for human to read, the easier for LLM to learn and generate. Abstractions also benefit the model, it does not need to generate a working 2s complement, just a working call to addition of abstracted types.
And just in my experience, I feel everyone is slowly learning, all models are better at the common thing, they are better at bash, they are better at Python and JS, and so on. Everyone trying to invent at that layer has failed to beat that truth. That bootstrapping challenge is dismissed much too easily in the article in my opinion.
I think the main reason not to go full-throttle into "vibes -> machine code" (to extrapolate past doing it in C) is because we have a history of building nested dolls of bounded error in our systems. We do that with the idea of file systems, process separation, call stacks, memory allocations, and virtual machines.
Now, it is true that vibes results in producing a larger quantity of lower-level code than we would stomach on our own. But that has some consequences for the resulting maintenance challenge, since the system-as-a-whole is less structured by its boundaries.
I think a reasonable approach when using the tools is to address problems "one level down" from where you'd ordinarily do it, and to allow yourself to use something older where there is historical source for the machine to sample from. So, if you currently use Python, maybe try generating some Object Pascal. If you use C++, maybe use plain C. If there were large Forth codebases I'd recommend targeting that since it breaks past the C boundary into "you're the operator of the system, not just a developer", but that might be the language that the approach stumbles over the most.
I see a lot of "vibe-coding" related articles, but I don't see a lot of shipped projects/products via "vibe-coding". I would like to find some examples instead of this kind of articles ?
It sounds like his main gripe of vibe coding is it robs you of the satisfaction as a programmer in solving the problem. I don't disagree, but the preferences of programmers are not necessarily the main driving force here behind these changes. In many cases it's their boss and their boss doesn't really care.
It's one thing to program as a hobby or to do programming in an institutional environment free of economic pressures like academia (like this educator), it's another thing to exist as a programmer outside that.
My partner was telling me her company is now making all their software engineers use ChatGPT Codex. This isn't a company with a great software engineer culture, but it's probably representative of the median enterprise/non SV/non tech start employer than people realise.
Never used C much, but I would assume it is more LOC than a newer language with more features. Less code is a fairly important feature for LLMs with relatively limited context windows.
I also enjoy coding! It’s fun. It’s also only about 10% of my job as a software developer, and I can and do use an LLM for it whenever I can find an opportunity. The author is a professor. Not to disparage that perspective, but she paints a picture of the joys of programming that are overshadowed in environments where you are actually building real world robust systems with clueless users, vague requirements, shifting budgets and priorities, etc.
As to why not use C, or assembly, it’s not just about the code, but the toolchains. These require way more knowledge and experience to get something working than, say, Python - although that has its own rather horrible complexities with packaging and portability on the back end of the code authoring process.
I think you're going to need a superhuman intelligence's idea of a super-superhuman intelligence at the very least if you're going to expect C programs that are memory safe.
I'll admit that I'd like to do a programming challenge with or without AI that would be like "advent of code" in assembly but if it was actual "advent of code" the direct route is to write something that looks like a language runtime system so you have the dynamic data structures you need on your fingertips.
I do vibe code in C. From what I understand, Ruby is written entirely in C. It's a wonderful high-level language experience on top of such a storied runtime as C (truly!).
What people miss is that vibe coding actually is coding, except the code are your prompts and the LLM is the compiler.
The problem here is that human languages are terrible programming languages and LLMs are terrible compilers.
Maybe I'm still in denial about the benefit of AI code design, but when I have an initial set of requirements for a program, the design begins. That is just a set of unanswered questions that I address with slowly growing code and documents. Then the final documents and code match the answers to all the questions that rose from the answers of previous questions. More importantly, I know how the code answers them and someone else can learn from the documentation. Since the invention of "velocity" I feel like much of the industry treats code and programmers like tissues. Wipe your nose and throw it away. Now we have AI-based automatic tissue dispensers and Weizenbaum's gripe about programmers creating work for themselves other than solving the requirements of the actual problems continues.
If you're going to vibe code on legacy code, use the languages used there. If you're going to vibe code something new, then I recommend Rust. There are few cases where I would vibe code something brand new in C, mainly when building a library I'm going to need to use from other C programs.
> why not do it in C?
Well, because you can do it in Fortran, of course!
What else do you want? Multidimensional arrays out of the box, fast loops, native cuda support, trivial build and packaging system, zero version churning... all of this just with the bare language. It's the anti-python! The perfect language, you could say! Strings and i/o are a bit cumbersome, agreed, but your llm can take care of these without any trouble, no matter the language.
I would say, because time to review is the most important metric in vibe coding.
I prompt my agents to use proper OO-encapsulated idiomatic ruby paradigms. Your goal should be reduced cognitive load.
Even if you never write a line of code, you will still need to understand your problems to solve them.
"Vibe debugging" will get you stuck in loops of hallucinated solutions.
To answer the question literally, vs discuss "is vibe-coding good": The more tricky details in a language, the more I've seen LLM-first coding struggle. Rust, for instance, often leads to the model playing whack-a-mole with lifetime or borrow checker issues. It can often get to something that compiles and passes the tests, but the process gives me some pause in terms of "what am I not checking for that the whack-a-mole may have missed."
In C, without anything like a borrow checker or such, I'd be very worried about there being subtle pointer safety issues...
Now, some of that could be volumes of training data, etc, but Rust is widely discussed these days in the places these models are trained on, so I'm not certain it's a training problem vs a attention-to-detail across files problem. I.e., since LLMs are trained to mimic human language, programming languages that are most procedural-human-language-like (vs having other levels o fmeaning embedded in the syntax too) may exactly be those "LLM-friendly" languages.
Alright, the whole article stands on the lifting done by the concept of "vibe coding", which is not just asking an LLM to write some code, scan it quickly to check if it at least makes somewhat sense and then accept it. It is based on pure vibe coding, where the user literally has no idea what's being produced.
After having understood the context, I still believe that a strongly typed language would be a much better choice of a language, for exactly the same reason why I wouldn't recommend starting a project in C unless there is a strong preference (and even then Rust would probably be better still).
LLMs are not perfect, just like humans, so I would never vibe code in any other environment than one in which many/most logical errors are by definition impossible to compile.
Not sure if C is worse than python/js in that respect (I'd argue it is better for some and worse for other, regarding safety) but Java, Swift, C#, Go, Rust, etc. are great languages for vibe coding since you have the compiler giving you almost instant feedback on how well your vibe coding is going.
My gut reaction is, if AI was really good at vibe coding all the infra it could be nice, but getting C deployed and productized is the potential challenge. The "roads" we built for hyper scaling apps doesn't strike me as C friendly. And, even with the friendlier deployment strateies on next, python, etc, AI still slips up a lot.
I don’t buy that LLMs won’t make off-by-one or memory safety errors, or that they won’t introduce undefined behavior. Not only can they not reason about such issues, but imagine how much buggy code they’re trained on!
> all the way to the borderlands of active anxiety—not quite understanding what Claude just wrote.
This is a big issue, personally. I write Python and bash these days and I love that we're not bottlenecked by IDE-based autocomplete anymore, especially for dynamic languages and a huge amount of fixing and incremental feature work can be done in minutes instead of days thanks to AI being able to spot patterns. Simultaneously I'm frustrated when these agents fail to deliver small changes and I have to jump in and change something I don't have a good mental model of or, worse still, something that's all Greek to me, like Javascript.
The vast majority of software models are trained on have little to no standards and contains all kinds of errors and omissions.
And these are systems that require a human in the loop to verify the output because you are ultimately responsible for it when it makes a mistake. And it will.
It’s not fun because it’s not fun being an appendage to a machine that doesn’t know or care that you exist. It will generate 1200 lines of code. You have to try and make sure it doesn’t contain the subtle kinds of errors that could cost you your job.
At least if you made those errors you could own them and learn from it. Instead you gain nothing when the machine makes an error except the ability to detect them over time.
I think if you don’t know C extremely well then there’s no point vibe coding it. If you don’t know anything about operating systems you’re not going to find the security bugs or know if the scheduler you chose does the the right thing. You won’t be able to tell the difference between good code and bad.
"If you're going to vibe code, why not do it in assembly?"
Many people I've seen have taken existing software and 'ported' it to more performant languages like C, Rust, etc.
LLMs are extremely efficient and good at translation.
The biggest question is maintainability and legibility. If you want it for your own proprietary software, this can (and probably is, generally) a good pattern if you can get the LLM to nail language specific challenges (e.g. memory allocation in C)
However, fewer people can write C code generally, and even fewer can use it to build things like UI's. So you're by definition moving the software away from a collaborative mechanism.
The abstraction layers were built for human maintenance. LLMs don't need that.
I did a goodly chunk of vibe coding over the summer and I found that the best language for me was Rust implementations with Python bindings for interface. A few reasons:
- Everything about rust enforcing correctness catches lots of bugs
- Using a high-level API means I can easily hand-check things in a repl
- In addition to tests, I required a full “demo notebook” with any PR — I should be able to read through it and confirm that all the functionality I wanted has actually been implemented
If the philosophy is (and it should be) “loc is free”, it’s worth thinking about how we can make LLMs produce more loc to give us additional comfort with correctness. Language choice is very much a way.
Honestly, I think this is a valid viewpoint, but perhaps C is too low level. The bottleneck in generating code with LLMs tends to happen at the validation step. Using a language that has a lot of hard to validate footguns isn't great.
While I am not a big fan of Rust, the philosophy is likely useful here. Perhaps something like it, with a lot of technical validation pushed to the compiler, could actually be really useful here.
Getting rid of the garbage collector with no major increase in human cognitive load might actually be a big win.
LLMs are good at in-distribution programming, so inventing a new language just for them probably won’t work much better than languages they were already trained on.
If you could invent a language that is somehow tailored for vibe coding _and then_ produce a sufficient high quality corpus of it to train the AI on them, that would be something.
Even experts create C/C++ code that is routinely exploited in the wild (see: pegasus malware, Zerodium, Windows zero days, Chrome zero days, etc.). No, please don't vibe code anything security critical, and please don't create unnecessary security risk by writing it in unsafe languages such as C/C++. The only advantage I can see is it creates some fun easy targets for beginning exploit developers. But that's not an advantage for you.
I like the idea of reimagining the whole stack so as to make AI more productive, but why stop at languages (as x86 asm is still a language)? Why not the operating system? Why not the hardware layer? Why not LLM optimized verilog, or an AI tuned HDL?
> Or hell, why not do it in x86 assembly?
I do vibe code in C; I'm not a C programmer and I certainly couldn't do a security audit of any serious C codebase, but I can read and understand a simple C program, and debug and refactor it (as long as it's still quite simple).
And it's super fun! Being able to compile a little C utility that lives in the Windows tray and has a menu, etc. is exhilarating.
But I couldn't do that in assembly; I would just stare at instructions and not understand anything. So, yes for C, no for assembly.
It's so refreshing to see a proper website these days, no js, no cookie banners, just hypertext. Your part about still enjoying programming really resonated with me. I still get so much joy out of programming after 20 years of doing it, it's still just as exciting to learn new things, and I am definitely not running out of new things to learn.
I would absolutely love to teach programming to non-programmers. I have also been offered a job at the technical school where I graduated. But remembering how uninterested the vast majority of my classmates were back then discouraged me from even trying. I guess what I'd want is a teach a room full of people excited to learn about programming.
No need for using assembler, LLMs should be writing machine bits directly into executables. It is also fairly simple to teach them how to do it. Provided we have some executable that was written in some human-readable computer language. We can read through the bits of the executable, and describe each portion using English, based on the description of what the original human-readable language is doing. This new model will only learn the English representation of chunks of bits and how they go together into an executable. After learning several billion such narrated executables it will be excellent at writing machine code.
Software development jobs must be very diverse if even this anti-vibe-coding guy thinks AI coding definitely makes developers more productive.
In my work, the bigger bottleneck to productivity is that very few people can correctly articulate requirements. I work in backend, API development, which is completely different from fullstack development with backend development. If you ask PMs about backend requirements, they will dodge you, and if you ask front-end or web developers, they are waiting for you to provide them the API. The hardest part is understanding the requirements. It's not because of illiteracy. It's because software development is a lot more than coding and requires critical thinking to discover the requirements.