I won't deliberately use AI for programming
mahdikarimi.comI strongly disagree with this perspective. I have found GPT4 in particular to be very helpful in learning new programming languages and improving my overall coding. I still solve problems myself and I still read books, but GPT4 is the TA that I can have a conversation with about a piece of code. It's all about how you use it. If you just ask it to tell you complete answers or generate code on a blank page then you're doing yourself a disservice.
To me GPT-4 has been very valuable when I already know the gist of what I need done, as in: I've done it before, I know the techniques and the right keywords I need, I know the tools I'll use, etc. but can't remember exactly the right incantation and would need to go read references, search Google, and so on.
Instead I pop by ChatGPT and ask it what I need done, the tools I'm using and let it write me an answer that I double-check to see if it matches what I'm looking for. It's definitely saved me a lot of time, I still go read the documentation but I have a much narrower point to start from.
I would never just copy-paste whatever it spits out, I don't trust it to generate code nor will I ever trust it to be fed with intellectual property in the prompt (mine or my employer's) but as a general assist for techniques and tools that I've been familiar with, and which could require some researching I do think it has pretty good value.
Yeah this logic would have us writing everything in assembly and only using textbooks.
I believe there's a inherent benefit in learning assembly and using textbooks because it helps you better understand the software you are writing with any other language. learning hard things the hard way is good.
Oh for sure! But you wouldn't argue to do this exclusively though
I wish more people would know Asm just so they can realise how much computing power they're wasting (multiplied by however many users...) when they've seen the limits of the machine.
I find it really helpful when dabbling in a language that you haven’t used much.
For example: If you’re an expert in language A, and you want to do something common in A in language B, you can ask GPT to show you the idiomatic way of doing it in B and it will usually lead you down the right path (or tell you it’s not possible).
It's a really bad TA that has no self awareness of its limitations. You are well aware that it hallucinates, right? You probably have observed it yourself in domains you're familiar with. But how would you recognise a hallucination in something that you have no familiarity with?
"Learning something new" from LLMs is like trying to learn something new from a con artist. Sure, they might actually tell you the truth, but having little knowledge of something is exactly the worst possible state to be in while trying to figure out what's true and what's hallucinated.
When it comes to programming, when an LLM hallucinates something in an area I'm not familiar with, it's usually very obvious that it is not correct because it just does not work at all. For me, programming hallucinations have never fallen into the case where it appears like everything is working but actually isn't doing the correct thing.
So then I just forward that back to the model, or in the very worst case use my own brain to fix the problem the LLM generated.
In either case, I'm still better off than had the LLM not existed, because even an incorrect solution is closer to the correct solution than nothing at all.
I now have something that's close to solving my problem that I wouldn't have been able to come up with solely on my own. It just needs a little tweaking to be correct, which I can muster my way through with a little help from the LLM or Google.
You are talking about most obvious hallucinations such as inventing a non-existent API.
However, those are indeed trivial. What's not trivial is not using APIs that exist for your particular problem; using obsolete patterns; not recognising that a particular approach is a dead end; not recognising potential future problems. All those problems fall in the same bucket of not knowing what you don't know, yet having a (seemingly fine) solution, which is worse than not having a solution, because that would force you to go and figure things out yourself (presumably reading recent documentation, etc).
I recognise that some people approached programming in the same way before LLMs, copying stuff from SO and adjusting till it works without ever understanding what they're doing. I guess LLMs can be seen as a neat extension of that "learning style" (which btw is precisely what OP warns against), but it does seem somewhat dysfunctional.
I don't think copying and pasting from stack overflow then fudging things until it works is always quite the same thing as using an LLM to help write code.
I've just spent the month of August learning to use Godot 4.0 with C#. Resources for this topic on the internet are scarce, Google only wants to show me the official Godot documentation and YouTube videos (which I don't watch because I don't like to learn in this way).
Sure, I could spend my time reading the official docs cover to cover, but I much prefer to get my hands dirty. I'm not a novice game programmer, I've written my own game engines, used Unity and published games. I've got the underlying knowledge of how Godot might work, but I'm unclear as to how to accomplish specific goals I'm trying to achieve.
And absolutely, I could just put everything into Google, and probably find correct documentation for what I need. Or I could just write "// Interpolate from current position to camera" and have Copilot spit out "transform3d.interpolate_with" along with supporting code specific to the code I have right here, which also references functions I don't even know existed. This way, I'm learning the "API landscape" in a sense.
Godot 4.0 is new enough (and C# used with Godot used so infrequently in online resoures) to the point where Copilot literally can not produce the correct output basically ever. The API changed and everything it outputs is subtly incorrect, either generating code that is now obsolete, or that the code it's generating no longer functions because of the API change.
When this happens, I just dive into the docs as a backup strategy. But never as my first choice.
Is this worse than not having Copilot? I don't think so, but it seems like we probably won't agree on that. I still feel like I've 'learned' Godot (I at least know more now than I did on August 1st). I'm able to synthesize the code more easily on my own thanks to the starting points provided by the LLM. And I'm also writing tutorials on how to use Godot, further solidifying the things the LLM showed me in my own mind.
I'm not saying LLM's are a "one stop shop" for learning. I'm just saying it's another tool. One that I think is a little shortsighted to just completely disregard because it's sometimes incorrect.
I'm on board with your point here
My experience has been that the hallucinations in GPT4 are actually pretty rare. But in any case, if I choose to use code it suggests I ask it for explanations and then I verify those myself by other means, e.g. tests. I think it's too strong to call it a really bad TA. I'd say it's an imperfect TA and you need to check it's work, but it's work still has great value.
It's not just things that can be caught with tests. You wouldn't know if you got recommended an obsolete API, a dated pattern, or a charged foot gun, and if you're looking up docs for every suggestion I doubt that'd save you much time compared to reading docs through to begin with.
I can definitely see those things being problems, but they are much more likely to occur when asking an LLM to generate code for you. That's not the best coding use case for LLMs IMO, it's much better to provide it code already written and ask it for explanations, bug fixes, refactoring etc. Then it rarely introduces new API calls etc
No, it's more like getting bad advice from Stack Overflow or Reddit.
Usually you notice it's broken because it doesn't work.
There may be some advice that seems to work, but has subtle issues. (For example, race conditions.) Having more experience can help in spotting these problems.
Either way, copying code blindly isn't a good idea. In a professional situation, better testing and code review can help.
Yes, but collectively we understand that SO or Reddit are unreliable, plus it's usually one-way and we don't see people posting bad advice defending it just for us. LLMs, on the other hand, are extremely convincing, while being even less trustworthy than SO/Reddit.
Just make a mental experiment and imagine that every comment here praising LLM coding skills is actually about copypasting stuff from SO. Does it not seem alarming to you?
I don't think it's any more alarming than people posting that they find Stack Overflow useful sometimes. That's why it became popular, right?
Similarly for searching the Internet. Internet searches are potentially dangerous if you can't tell good answers from bad. But if you treat it as a source of hints that you need to verify yourself, it's a pretty good source of hints.
Many of us have learned quite well that LLM's are unreliable. Someone posts about the problem whenever it comes up. It's something close to conventional wisdom.
It's still surprising the first time you see it hallucinate, though. You have to see it for yourself. Once you've seen it a few times, it isn't so convincing anymore.
It's basically a form of rubber duck debugging.
I also use for quickly writing tiny programs to isolate and test a specific piece of functionality.
I think that for some types of programmers, AI-assisted programming feels no different from what they already do.
Those types feel that the end goal of 'working code' is all that matters. Their definition of 'working' meaning that the functional requirements of the feature are met.
That mindset is an extreme. A developer's job is to solve a problem for someone, not to code, but copy/pasting code without understanding as a consistent behavior is a recipe for eventual collapse of a codebase.
I see Copilot and other LLM code generation as methamphetamine for that sort of programmer. They will feel great, but the situation around them will degrade, those surrounding them will be unhappy, and eventually it will be clear the behavior was unsustainable.
From a different angle, I would feel uneasy giving others access to my proprietary data (code), and also accepting LLM generated code into my companies products. The legal rules don't seem fully sorted.
As a front-end lead and long time game programmer, I've been using copilot at work and home since it was invite-only. This assessment isn't accurate, at least in my case. Copilot mostly:
- Writes the same code (often verbatim) I was about to write, often multiple lines of it. "Ok, next I'll loop over the rigidbodies and apply the force to the ones in range- oh look the loop is already there"
- Gives me some API calls I didn't know about, much easier than finding a stackoverflow post. There's generally not much enlightenment to be had diving deep into the formatting of java.date or some such - if I just want to format a date and move on, it's awesome being able to type a comment "//format the date as.." and get the code. The IDE will yell at me right away if it gave me something deprecated, and I'll hover over the unfamiliar bits it put there anyway to make sure everything is sensible.
- Solves the small problem I'm looking at in a way I didn't think of, or even alerts me to an error in my thinking frequently enough - "Why is it doing that? Oh yeah, I really should've done that.."
My codebases haven't suffered, and I'm still diligent to keep them maintainable, well-tested, and fundamentally sound.
Overall, it speeds things up a lot and frees mental space for me to think about the big picture more. I generally understand the code being put out just as well as any other code I've written - be honest, you don't read a book on every API call you copy from Stack Overflow. The beauty of a good abstraction is that we generally don't have to.
If anything I think it's helped me become a better programmer over the past year, elevating the mental level of abstraction I work at somewhat.
I can see what you said being a problem for somebody just starting out though. And as the author said (and I found trying to learn Rust with Copilot on) it can even be an annoying distraction in that case.
As an aside, copilot and gpt have certainly degraded lately with hallucinations way up (copilot chat has been extra disappointing lately), maybe to save server costs. Could be why we're seeing more negative sentiment.
> be honest, you don't read a book on every API call you copy from Stack Overflow.
I don't, because I don't copy code from SO in the first place. But when I'm using or encountering an API that I'm not terribly familiar with, I absolutely do read the documentation for it. It's part of my continuing education and how I maintain a diverse professional skillset.
Same here, I've very rarely ever copy/pasted code out of stackoverflow.
The response to my comment above is an example of what I was describing, and I don't mean it as an insult (though I understand if it is taken that way). People don't all treat software development the same.
The 'rush to action' types are more willing to shortcut the thought part of the work that others might. They are more willing to embrace AI codegen, as coding for them is not about reifying understanding.
If I were to adopt AI code generation, I'd still have to read the code to understand, which nullifies some of its value.
I do think AI code generation as a way to start designs could be good. But again, if I need to expose company code to do that, it probably isn't worth it.
> coding for them is not about reifying understanding.
I don't agree with the implication that I have a deficit in understanding. I would more say that I focus my understanding where it matters.
For example, in web dev this would be a thorough fundamental understanding of the DOM and what interacts with it (JS/HTML/CSS, especially the warts of JS), the performance/responsiveness costs of doing things certain ways, what runs synchronously and how to use that to make the best user experience (avoid flashing/repainting with a quick synchronous thing but longer things should be async..), the overarching architecture of your codebase and how modules should fit into it, what your internal API's do..
If you're rock solid on all of that, the really important stuff of your domain, then you'll have smooth sailing whatever you do. The rest is quite often incidental. Copilot/stackoverflow/some guy on IRC says org.apache.util3.json.JSON.IsValidJson will validate my json, and I already have org.apache.util3 installed? Great, moving on to the rest of the work I have to do building this service..
If that API call blows up on me later, I'll investigate deeper, but my sense of what's important to investigate deeply rarely fails me at this point in my career. The org.apache.util3 probably have little interesting to teach me, but when Firefox started supporting raw JS modules, you bet I thoroughly looked into that.
I think it's a difference in approach and goals. One approach isn't better than another -- it all depends on the person and what their overall goal is.
Personally, I've found that very often, things I've learned that were apparently unrelated to the task at hand gives me a key insight in how to approach the task at hand in a better way. That broad knowledge base is a large part of the value I bring to the job. This continuing education is not limited to technological topics -- any knowledge from any domain may be useful to me as a dev.
This is why I go out of my way to learn things as deeply as is practical, even (or especially) if that knowledge is much more than what I need for the immediate task at hand. I'm taking a natural opportunity to advance my overall knowledge and skillset. The immediate task at hand is only part of what I'm being paid to do. Another part is expanding my knowledge base. A huge part of what I want out of any job is to expand my education.
Other devs don't have that as their goal, and there's nothing at all wrong with that. It's just a different style and different overall goals, is all.
I wasn't implying you lacked understanding.
I was describing two different general approaches people use to write software.
Sorry to use your post as an example. I don't know anything about you outside your posts. Please don't take it personally.
I do so many things manually that have been successfully automated for a long time. Washing dishes, splitting firewood, grinding coffee, owning manual transmission cars, I could go on. Some things are subjectively better like splitting firewood; It's more work but quieter. Some things are objectively better; washing dished by hand are cleaner. I don't think about it too much.
I guess I'll just add programming to that list and not think about it too much.
I gotta side with the dishwasher. Mine heats the dishes so hot my hands would burn off doing it, and it uses 5 gallons of water for a full load.
Dont forget the chemicals that would also hurt your hands.
washing dishes by hand are absolutely NOT cleaner and ultimately extremely wasteful in terms of water used.
use a dishwasher from the last 20 years.
Clearly you have not seen the dishwasher in my apartment. Trust me, washing by hand is more effective.
Dishwashers are better than hand in literally every sense.
More water efficient, chemical efficient, cleaner since the water gets MUCH hotter.
I agree, with a good modern dishwasher. My parents have a wonderful Bosch dishwasher that is quiet, efficient, and most importantly, can handle anything you throw at it. Conversely, the dishwasher at my apartment is junk; I have to rinse and scrub dishes before putting them in the dishwasher or they won't come out clean.
But you do use a car, instead of walking everywhere.
This is a bit beside the point. They also use dishes instead of leaves, presumable a modern axe instead of a piece of stone, etc.
To me it’s about finding the sweet spot between staying connected to the thing that you’re doing for the purpose of keeping life interesting/fulfilling and utilizing your time wisely.
Driving stick is like shooting manual photos. Not necessary in 2023, but can be a lot more fun than the alternative, and enables levels of control that cannot be found with automated solutions.
Choosing to walk is like choosing to forego fire altogether.
My point is that AI is just a tool for programming and that I see it as more comparable to the difference between walking and driving than the difference between driving stick and automatic.
Eh, I can’t really agree, but I suppose this is relative to each person’s interests.
To me, the analogy to walking would be like foregoing the computer entirely and using an abacus, or sticks in the sand.
The end result of writing code manually or automatically is still a program made from code that must be maintained. Some people like more control over the code.
The end result of using an automatic or manual transmission is still driving. Some people like more control over the operation of the transmission because of the finer grained control over the output of the car that it enables.
> while attempting to grasp new concepts, numerous questions might crop up that encourage you to delve deeper and acquire additional knowledge
So far GPT-4 has proven to be much more helpful in giving me pointers or straight up answers (that I DO check!) to some of my questions than any other source, tool or entity in my life. I've explored and lightly discussed topics I never knew I was interested in.
I have gone past the point of giving a shit. Unless it's something I really care about the minuscule details for I'll get ChatGPT to write the main chunk of code and then fix the bugs. It's no different than having a junior dev working for you, except it's quicker and doesn't piss off to lunch or go sick when you need them.
I never need this. Just the work to get the code out of ChatGPT correctly is usually more effort than writing it. And besides - most of the time there is a huge amount of context and ChatGPT knows nothing about it. I touch dozens if not hundreds of files every day. Doing a little tweak here or there which rarely takes more than a few seconds to do. And the rest of the time I spend thinking and designing.
> It's no different than having a junior dev working for you
In my experience it's completely different.
A junior dev who wants to produce a PDF automatically will have to spend a few hours evaluating all the library options and learning their usage. But the code will certainly be free of syntax errors and will produce not-obviously-wrong output before they send it for code review.
ChatGPT will select a library and know how to use it instantaneously - and yet, might call methods that don't exist. Which any human developer would have caught on the very first test run.
They do have certain things in common though - ChatGPT certainly comments code like a beginner programmer :)
GPT4 is like 100:1 hits to misses for me.
Recently I switched to a different case for my home NAS. The drive caddies had a tiny cutout for a label, like 0.75 inch x 1.5 inch.
I decided to see if Chat GPT could take care of it. I asked for it to write LaTeX that would produce rectangles of that size with a light gray border, with the serial number of each drive in the rectangle.
On the first pass it got it basically right. Rectangles all the right size, right border, and all the right serial numbers.
The rectangles were all touching each other so I asked it to put a half inch between each and it did that. Then I decided I wanted fixed width font, and it accommodated that as well.
Then just for fun I asked it to draw a dinosaur using LaTeX. It advised me that this isn’t a good use of LaTeX and then used shape primitives to draw a plausible looking dinosaur.
…and the library might be obsolete, unmaintained, or outright a wrong choice for the task at hand.
> doesn't piss off to lunch or go sick when you need them
It doesn't until it does I think.
I'll worry when it starts a union :)
I agree with the author. The idea of "collateral knowledge" or "chain of learning" is definitely important for personal understanding and learning. However, I think depending on the person, ChatGPT actually helps the chain of learning rather than hinders.
I have mixed feelings about this. I switch back and forth between two editors: Emacs for Clojure and other lisps (and Org Mode and Magit), and VSCode with Copilot for, well, most everything else. This ad hoc setup provides a little bit of "personal A/B testing" -- feeling the difference Copilot makes.
When I was learning Go I had Copilot on most of the time. I was amazed at how much progress I could make despite being new to the language. And, when switching to Emacs, I'd notice myself reflexively waiting for Copilot to supply autocompletions that weren't there.
Yet, strangely enough, I can actually write Go code now (with or without Copilot). All the troubleshooting, refactoring, redesigning, bug fixing, etc. that I still had to go through saw to that. (Presumably having programmed already for many years didn't hurt.) Repeated and quick exposure to the relevant idioms supplied by my tooling seems to have helped at least as much as it set me back.
On the lisp (Clojure, Elisp, ...) side of things, I have found Copilot (and ChatGPT) much less helpful, presumably because of the relative paucity of training data. Simple things such as matching parentheses seem to elude these tools, and hallucinations are worse and more frequent. I'm still feeling out how this difference w.r.t VSCode/Copilot and other languages affects my experience and the quality of my output, but it definitely feels different (and, frankly, a little clumsier).
Over time I've learned how helpful different kind of tools are for making software. Learning one's editor well. Writing good (and fast) tests. Using linters and code formatters. Using type systems when available. The new AI tools certainly involve trade-offs, but as I gain experience with them I am becoming convinced that putting them aside will make programming a different, and probably much slower, experience than what most programmers come to experience. (Slow can be good, but probably not what most of us want.)
> Repeated and quick exposure to the relevant idioms supplied by my tooling seems to have helped
This sounds exactly like what we know about how children learn language. The recommendation now for adults focuses on a large portion of full immersion in content like tv/movies with no translation. We pick up on patterns and rules from repeated exposure. Maybe this will inform how we teach programming too. I had Copilot on learning Rust and it alternately felt distracting and like cheating so I turned it off, but I think I'll turn it back on based on your experience.
As anything in life, this isn't a binary choice.
You can use an llm, while learning yourself.
I agree with the take on copilot being a hindrance on using your brain. While learning a new language it was really hard to understand whatever is being put in front of me (as autocomplete) is truly best practice or something tied together very loosely.
The extra time it takes you to google, and learn about strategies on how to code, and patterns, and design. This is what is actually valuable, being able to speak to these things in conversation when defending the code you wrote on a PR etc, it makes a difference.
I used Copilot for several months and there were times when I was “wow”ed and others where it’s just got in the way.
I recently decided to make my editor much more minimal and even went so far as to disable autocomplete entirely. So far I haven’t noticed a reduction in my productivity and actually find it much easier to think about what I’m writing since I’m not having to correct autocomplete and Copilot all the time. All the extra things popping up on the screen were really distracting and I find that for me, a minimal approach gives me more space to think deeply.
The main thing I find copilot good for is things that are easy to validate, but tedious (not hard!) to write. Stuff like colors for different statuses, or error messages.
I actually love it for writing error messages. Keeps me in flow better not having to switch to writing Human English every five lines when something fails validation.
I agree, in fact I used it to generate a list of colors for a very simple color picker at work. It was very helpful. That said I could also have a chat interface do that for me when I want it, so I can keep my editing experience distraction free.
I used Copilot full time for about four months writing Rust and Python, and then stopped completely.
Problem is, LLMs are really good at uninsightful, repetitive, boilerplate-y bits of code that shouldn't be there. The moment I get to anything remotely complex or subtle, it either doesn't grasp what I'm doing, needs more coaxing than it's worth, or worst of all introduces subtle bugs. It just incentivises me to write mountains of pointless code instead of stopping and thinking if it even needs to be written in the first place.
What we get from code writing LLMs are exactly the same kind of "improved productivity" we got a decade ago with IDEs autogenerating Java boilerplate. It might help in the short term, but long term it just masks the pain that drives tools and skills getting better, more concise, less repetitive, more insightful.
On the other hand, I'm really looking forward to tools that will be able to figure out how much "insight per line of code" our code has, some sort of "Kolmogorov complexity" but with LLMs. Anything too predictable, anything LLMs can easily fill in is a good code smell signal.
I’ve found that GPT-4 now fills the role that Google once did for me when learning new things.
For whatever reason the Google results just aren’t as useful as they used to be. Highly specific queries return very generalized results, and it takes a lot of effort to find something relevant.
With ChatGPT I can ask it how to do just about anything in any language and it nearly always gives me exactly what I need.
Some of this has to do with Google pushing sites like geeksforgeeks above more helpful blogs.
Me neither. If I'm responsible for all the code I write, then "the AI did it" is not an acceptable excuse if it happens to be wrong in some subtle way.
IMO learning is at the service of building. I learn what I need to build. If GPT can do the first 30% of any project, then I can focus my learning on the remaining 70%. Just think of GPT as another layer of abstraction.
Sure, pure learning is enjoyable but also ephemeral. Building/doing = learning, yes, but no need to do everyhting.
Some people (like, for example "Conscience of a Hacker" author Loyd Blankenship) still like to make furniture by hand.
Despite the widespread availability of flatpacked IKEA style furniture, there is still the desire for the sheer joy of craftsmanship... and there is still demand for the end product.
That's right!
You can use AI for learning.
I know a lot of people who learn by looking at code and then playing with it to understand it. Generative AI is great for those people - they can quickly get code they can start with.
Different strokes for different folks.
Agreed. Learning is one of AI's stronger points. You can get examples and explanations for code that's seemingly non-existent according to Google.
i think everyone learns differently, and one person's "toggling between 30 tabs" is another's "having this explained to me personally over and over"
What a luddite argument! AI can show you previously unknown ways, often the pragmatic and idiomatic ways to solve problems. It can also explain code in depth. I don‘t know how I‘d have quickly mastered the shitty "drool syntax" I had the displeasure to work with today. No other tool allowed one to become fluent in a new language or framework this fast, ever before.
Sounds the same like people who rejected IDEs. Or even syntax highlighting. Yes, those people existed and some might still rawdog xml and java in vi today.
49 20 70 72 65 66 65 72 20 74 6F 20 77 72 69 74 65 20 6D 79 20 63 6F 64 65 20 69 6E 20 48 65 78 2E
01100010 01101001 01101110 01100001 01110010 01111001 00100000 01101111 01110010 00100000 01100010 01110101 01110011 01110100 00100001
(ps. vi might not necessarily be an ide by itself (though plugins can change that) , but the unix command line in its totality definitely can count as one. Sometimes it's just faster to jump into vi, fix a problem, and then continue. )