I wonder how many people that use agents actually like "programming", as in coming up with a solution to the problem and then being able to express that in code. It seems like a lot of the work that the agents are doing is removing that and instead making you have to explain what you want in natural language and hope the LLM doesn't introduce bugs
I like writing code, and it definitely isn't satisfying when an LLM can one-shot a parser that I would have had fun building for hours.
But at the same time, building a parser for hours is also a distraction from my higher level ambitions with the project, and I get to focus on those.
I still get to stub out the types and function signatures I want, but the LLM can fill them in and I move on. More likely I'll even have my go at the implementation but then tag in the LLM when it's not fun anymore.
On the other hand, LLMs have helped me focus on the fun of polishing something. Making sweeping changes are no longer in the realm of "it'd be nice but I can't be bothered". Generating a bunch of tests from examples isn't grueling anymore. Syncing code to the readme isn't annoying anymore. Coming up with refactoring/improvement ideas is easy; just ask and tell it to make the case for you. It has let me be far more ambitious or take a weekend project to a whole new level, and that's fun.
It's actually a software-loving builder's paradise if you can tweak your mindset. You can polish more code, release more projects, tackle more nerdsnipes, and aim much higher. But it took me a while to get over what turned out to be some sort of resentment.
I agree, agents have really made programming fun for me again (and I say this as someone who has been coding for more two decades - I'm not a script kiddy using them to make up for lack of skill).
Configuring tools, mindless refactors, boilerplate, basic unit/property testing, all that routine stuff is a thing of the past for me now. It used to be a serious blocker for me with my personal projects! Getting bored before I got anywhere interesting. Much of the time I can stick to writing the fun/critical code now and glue everything else together with LLMs, which is awesome.
Some people obviously like the fiddly stuff though, and more power to them, it's just not for me.
Parsing is an area that I'm interested in. Can you talk more about your experience getting LLMs to one-shot parsers?
From scratch LLMs seem to be completely lost writing parsers. The bleeding edge appears to be able to maybe parse xml, but gives up on programming languages with even the most minimal complexity (an example being C where Gemini refused to even try with macros and then when told to parse C without macros gave an answer with several stubs where I was supposed to fill in the details).
With parsing libraries they seem better, but ultimately that reduces to transform this bnf. Which if I had to I could do deterministically without an LLM.
Also, my best 'successes' have been along the lines of 'parse in this well defined language that just happens to have dozens if not hundreds of verbatim examples on github'. Anytime I try to give examples of a hypothetical language then they return a bunch of regex that would not work in general.
A few weeks ago I gave an LLM (Gemini 2.5 something in Cursor) a bunch of examples of a new language, and asked it to write a recursive descent parser in Ruby. The language was nothing crazy, intentionally reminiscent of C/JS style, but certainly the exact definition was new. I didn’t want to use a parser generator because (a) I’d have to learn a new one for Ruby, and (b) I’ve always found it easier to generate useful error messages with a handwritten recursive descent parser.
IIRC, it went like this: I had it first write out the BNF based on the examples, and tweaked that a bit to match my intention. Then I had it write the lexer, and a bunch of tests for the lexer. I had it rewrite the lexer to use one big regex with named captures per token. Then I told it to write the parser. I told it to try again using a consistent style in the parser functions (when to do lookahead and how to do backtracking) and it rewrote it. I told it to write a bunch of parser tests, which I tweaked and refactored for readability (with LLM doing the grunt work). During this process it fixed most of its own bugs based on looking at failed tests.
Throughout this process I had to monitor every step and fix the occasional stupidity and wrong turn, but it felt like using a power tool, you just have to keep it aimed the right way so it does what you want.
The end result worked just fine, the code is quite readable and maintainable, and I’ve continued with that codebase since. That was a day of work that would have taken me more like a week without the LLM. And there is no parser generator I’m aware of that starts with examples rather than a grammar.
Thanks for giving details about your workflow. At least for me it helps a lot in these sorts of discussions.
Although, it is interesting to me that the original posting mentioned LLMs "one-shot"ing parsers and this description sounds like a much more in depth process.
"And there is no parser generator [...] that starts with examples [...]"
People. People can generate parsers by starting with examples. Which, again, is more in line with the original "one-shot parsers" comment.
If people are finding LLMs useful as part of a process for parser generation then I'm glad. (And I mean testing parsers is pretty painful to me so I'm interested in the test case generation). However I'm much more interested in the existence or non-existent of one-shot parser generation.
I recently did something similar, but different: gave Claude some code examples of a Rust-like language, it wrote a recursive descent parser for me. That was a one-shot, though it's a very simple language.
After more features were added, I decided I wanted BNF for it, so it went and wrote it all out correctly, after the fact, from the parser implementation.
Like three or four. very simple language: main function whos value is the error code, functions of one argument returning one value, only ints, basic control flow and math.
If I wrote down the prompts, I'd share them, but I didn't.
Please ignore the large amount of llm bullshit in here, since it was private while I did this, I wasn't really worried about how annoying and slightly wrong the README etc was. HEAD is better in that regard.
I guess I don't really understand the goal of "one-shot" parser generation, since I can't even do that as a human using a parser generator! There's always an iterative process, as I find out how the language I wanted isn't quite the language I defined. Having somebody or something else write tests actually helps with that problem, as it'll exercise grammar cases outside my mental happy path.
The comment that started this whole thread off mentioned LLMs oneshot-ing parsers. I didn't think an LLM could one shot a parser and I am interested in parsers which is why I asked about more info.
It's not a goal of mine but because of interests in parsing I wanted to know if this was something that was happening or if it was hyperbole.
By one-shot in my original post, I mean that it comes up with a decent, working implementation that I can then refine.
As opposed to getting there through incremental revisions where I must dictate the directions the LLM takes -- I don't necessary know the directions it should take because I might be agnostic about it.
I find success in breaking the problem down into tokenize and parse just like I do when writing parsers myself.
And definitely get it to generate tests every step of the way. The insane part is when the LLM can run tests itself and can iterate on code until all tests pass.
Or you extend it with a feature just by writing some failing tests and it does the rest.
Well, I mean, it sort of did one-shot the parser in my case (with a few bugs, of course). It just didn't one-shot the parser I wanted, largely because my definition was unclear. It would be interesting to see how it did if I went to the trouble of giving it a truly rigorous prompt.
> I still get to stub out the types and function signatures I want, but the LLM can fill them in and I move on. More likely I'll even have my go at the implementation but then tag in the LLM when it's not fun anymore.
This is the best part for me. I can design my program the way I want. Then hack at the implementation, get it close, and then say okay finish it up (fix the current compiler errors, write and run some unit tests etc).
Then when it's time to write some boiler plate / do some boiler plate refactoring it's extract function xxx into a trait. Write a struct that does xxx and implements that trait.
I'm not over the resentment entirely, and if someone were to push me to join a team that coded by creating github issues, and reviewing the PRs I would probably hate that job, I certainly do when I try to do that in my free time.
In wood working you can use hand tools or power tools. I use hand tools when I want to use them either for a particular effect, or just the joy of using them, and I don't resent having to use a circular saw, or orbital sander when that's the tool I want to use, or the job calls for it. To stretch the analogy developing with plain text prompts and reviewing PRs feels more like assembling Ikea furniture. Frustrating and dull. A machine did most of the work cutting out the parts, and now I need to figure out what they want me to do with them.
I do really like programming qua programming, and I relate to a lot of the lamentation I see from people in these threads at the devaluation of this skill.
But there are lots of other things that I also enjoy doing, and these tools are opening up so many opportunities now. I have had tons of ideas for things I want to learn how to do or that I want to build that I have abandoned because I concluded they would require too much time. Not all, but many, of those things are now way easier to do. Tons of things are now under the activation energy to make them worthwhile, which were previously well beyond it.
Just as a very narrow example, I've been taking on a lot more large scale refactorings to make little improvements that I've always wanted to make, but which have not previously been worth the effort, but now are.
I have to flip the question, what is it that people like about it? I certainly don't enjoy writing code for problems that have already been solved a thousand times. We reach for a dictionary, we don't write a hash table from scratch every time, that's only fun the first time you do it.
If I could go "give me a working compiler for this language" or "solve this problem using a depth-first search" I wouldn't enjoy programming any less.
About the natural language and also in response to the sibling comment, I agree, natural language is a very poor tool to describe computational processes. It's like doing math in plain English, fine for toy examples, but at a certain level of sophistication it's way too easy to say imprecise or even completely contradictory things. But nobody here advocates using LLMs "blind"! You're still responsible for your own output, whether it was generated or not.
Why do people enjoy going to the gym? Those weights have already been lifted a thousand times.
I enjoy writing code because of the satisfaction that comes from solving a problem, from being able to create a working thing out of my own head, and to hopefully see myself getting better at programming. I could augment my programming abilities with an LLM in the same way you could augment your gym experience with a forklift. I like to do it because I'm doing it.
If I could go "give me a working compiler for this language", I wouldn't enjoy it anymore, because I've not gained anything from it. Obviously I don't re-implement a dictionary every time I need one, because its part of the "standard library" of basically everything I code in. And if it isn't, part of the fun is the challenge of either working out another way to do it, or reimplementing it.
Once I solved an Advent of Code problem, I felt like the problem wasn't general enough, so I solved the more general version as well. I like programming to the point of doing imaginary homework, then writing myself some extra credit and doing that as well. Way too much for my own good.
The point is that solving a new problem is interesting. Solving a problem you already know exactly how to solve isn't interesting and isn't even intellectual exercise. I would gain approximately zero from writing a new hash table from scratch whenever I needed one instead of just using std::map.
Problem solving absolutely is a muscle and it's use it or lose it, but you don't train problem solving by solving the same problem over and over.
> Solving a problem you already know exactly how to solve isn't interesting and isn't even intellectual exercise.
That isn't typically what my programming tasks at work consist of. A large part of the work is coming up with what exactly needs to be done, given the existing code and constraints imposed by technical and domain circumstances, and iterating over that. Meaning, this intellectual work isn't detached from the existing code, or from constraints imposed by the language, libraries and tooling. Hence an important part of the intellectual challenges are tied to actually developing and integrating the code yourself. Maybe you don't find those interesting, but they aren't problems one "already knows exactly how to solve". The solution, instead, is the result of a discovery and exploration process.
Yeah but this is exactly why using LLMs doesn't actually preclude problem solving. You still have to do all these things. You just don't have to physically type out as much code.
To make a limping analogy, writing a novel actually requires the writing process. You can instruct an LLM to write prose, but the result won't be the same. I do a lot of thinking by coding, by looking up existing parts of the code base, library documentation and such, to decide how to best combine things, to determine what edge cases have to be solved and implementation decisions to be made. Once I know how things fit, I'm already halfway done. And it's usually more fun to do the rest myself than to instruct the LLM about all the details of the solution I have in mind. There are cases where using the LLM makes sense for truly tedious parts, of course, but it's not the majority of the work.
Yeah I would agree with "it's not the majority of the work".
This is what's making these discussions feel so contentious I think. People say "these are very useful tools!" and people push back on that. But then a lot of times it turns out that people pushing back just mean "they can't do the majority of my work!". Well yeah, but that wasn't the claim being made!
But then I'm also sympathetic, because there is a huge amount of hype, there are lots of people claiming the these things can do everything.
So it's just a jumble where the claims being made in either direction just aren't super clear.
If I'm having the same problem over and over, I'll usually copy the solution from somewhere I've already solved it, whether that be my own code, or a place online where I know the solution is
I think this is a good analogy! But I draw a different conclusion from it.
You're right that you wouldn't want to use a forklift to lift the weights at a gym. But then why do forklifts exist? Well, because gyms aren't the only place where people lift heavy things. People also lift and move around big pallets of heavy stuff at their jobs. And even if those people are gym rats, they don't forgo the forklift when they're at work, because it's more efficient, and exercising isn't the goal, at work.
In much the same way, it's would be silly to have an LLM write the solutions while working through the exercises in a book or advent of code or whatever. Those are exercises that are akin to going to the gym.
But it would also be silly to refuse to use the available tools to more efficiently solve problems at work. That would be like refusing to use a forklift.
Different strokes for different folks. I have written crud apps and other simple implementations thousands of times it feels like. My satisfaction is derived from building something useful not just the sale of building.
Complex argument parsing is something that I'd only generally be doing in python, which is handled by the argparse library. If I was doing it in another language, I'd google if there was a library for it, otherwise write it once and then copy it to use in other projects. Same with loggers.
Depends on how I'm extracting input from a config file, what kind of config file, etc. One of my favourite things to do in programming is parsing file formats I'm not familiar with, especially in a white-box situation. I did some NASA files without looking up docs, and that was great fun. I had to use the documentation for doom WAD files, shapefiles and SVGs though. I've requested that my work give me more of those kinds of jobs if possible, since I enjoy them so much
> Complex argument parsing is something that I'd only generally be doing in python, which is handled by the argparse library.
Yes, I'm referring to argparse. If you had to write a new script every few days, each using argparse, would you enjoy it?
argparse was awesome the first few times I used it. After that, it just sucks. I have to look up the docs each time, particularly because I'm fussy about how well the parsing should work.
> otherwise write it once and then copy it to use in other projects. Same with loggers.
That was me, pre-LLM. And you know what, the first time I wrote a (throwaway) script with an LLM, and told it to add logging, I was sold. It's way nicer than copying. Particularly with argument parsing, even when you copy, it's often that you need to customize behavior. So copying just gets me a loose template. I still need to modify the parsing code.
More to the point, asking an LLM to do it is much less friction than copying. Even a simple task like "Let's find a previous script where I always do this" seems silly now. Why should I? The LLM will do it right over 95% of the time (I've actually never had it fail for logging/argument parsing).
It is just awesome having great logging and argument parsing for everything I write. Even scripts I'll use only once.
> Depends on how I'm extracting input from a config file, what kind of config file, etc. One of my favourite things to do in programming is parsing file formats I'm not familiar with, especially in a white-box situation.
JSON, YAML, INI files. All have libraries. Yet for me it's still a chore to use them. With an LLM, I paste in a sample JSON file, and say "Write code to extract this value".
Getting to your gym analogy: There are exercises people enjoy and those they don't. I don't know anyone who regularly goes to the gym and enjoys every exercise under the sun. One of the pearls of wisdom for working out is "Find an exercise regimen you enjoy."
That's a luxury they have. In the gym. What about physical activity that's part of real life? I don't know a single guy who goes to the gym and likes changing fence posts (which is physically taxing). Most do it once, and if they can afford it, just pay someone else to do it thereafter.
And so it is with programming. The beauty with LLMs is it lets me focus on writing code that is fun for me. I can delegate the boring stuff to it.
ha, very apropos example. One of the things I was ecstatic to let an LLM write for me last week was a click cli.
Nobody finds joy in writing this kind of boilerplate, but there's no way to avoid it. The click API is very succinct, but you still have to say, these are the commands, these are the options, this is the help text, there is just no other way. It's glorious to have tools that can do a pretty good job at a first crack of typing all that boilerplate out.
These are the kinds of things I tend to write a library for over time, that takes care of the details that remain the same between use cases. Designing those is one interesting and fulfilling part of the work.
That's all fine and good, but there is always boilerplate that you can't design away.
Even the most succinct cli command definition and argument parsing library you could devise is going to require a bunch of option name definition.
It's just a fool's errand to think you can stamp out everything that is tedious. It's great that we now have tools that can generate arbitrary code to bridge that gap.
There are diminishing returns for sure, and this wasn't an argument against using LLMs for the tedious parts. It was an argument that most of the existing work isn't necessarily tedious to start with.
Do they? I would assume that the overwhelming majority of people would be very happy to be able to get 50% of the results for twice the membership cost if they could avoid going.
If you pay twice the membership, they provide you a forklift so you can lift twice the weight. I prefer to lift the weight myself and only spend half as much
Obviously I was referring to a hypothetical option where it's still your body that get stronger. Sticking with this metaphor - I don't care about the weights going up, but rather about my muscles getting stronger, and if there were an easier and less accident-prone way to do that without the weights, then I would take it in a heartbeat.
And going back to programming, while I sometimes enjoy the occasional problem-solving challenge, in the vast majority of time I just want the problem solved. Whenever I can delegate it to someone else capable, I do so, rather than taking it on as a personal challenge. And whenever I have sufficiently clear goals and sufficiently good tests, I delegate to AI.
I suspect you are in the vast minority. Most folks are moving weights around for the result feedback, the fitness. Similarly, a lot of engineers are writing code to get to the end result, the useable product. Not writing code to be writing code.
Anyway I indeed find LLMs useful for stackoverflow-like programming questions. But this seems to not be true for long as SO is dying and updated data on this type of questions will shrink I think.
Don’t agree with the assessment. At this point most of what I find LLM taking over is all the repetitive crud like implementations. I am still doing what I consider the fun parts, architecting the project and solving what are still the hard parts for the LLM, the non crud parts. This could be gone in a year and maybe I become a glorified product manager but enjoying it for the time being l, I can focus on the real thought problems and get help lifting the crud or repetitive patterns.
If you keep asking an LLM to generate the same repetitive implementations, why not just have a basic project already set up that you can modify as needed?
YMMV. No boilerplate is exactly the same, there is usually some level of business logic or customization. With current gen I can point to a couple different files, maybe db models, and write a quick spec in 30 seconds and let it run in the background implementing the backend routes I want. I can do other valuable things in parallel, I can also point it to my FE to implement the api calls to the BE. It’s for me much quicker than a template which I am still customizing.
Is it a substantial blocker? Nope, but it’s like I outsourced all the boilerplate by writing a sentence or two.
It is though, because it can do a pretty good job of every template.
I remember what I revelation it was a million years ago or so when rails came along with its "scaffold". That was a huge productivity boost. But it just did one specific thing, crud MVC.
Now we have a pretty decent "scaffold" capability, but not just for crud MVC, but for anything you can describe or point to examples of.