rbongers
It would also be nice to have work readily available related to the field I've been building skills in for over a decade that I know isn't going to disappear suddenly. Prompt engineering is already dead. I suspect any skills you learn now to utilize AI is not going to last more than a few years.
I feel like I'm taking crazy pills a little when it comes to this subject. Maybe everyone else already has ridiculous money saved, or has other things lined up, or are just ready to move into a Monastery. But for those of us in the middle of our careers and with no AI-proof capabilities the future is at the very least uncertain.
Personally, I enjoy the process of solving problems. I do not enjoy wrangling unpredictable AI agents.
This is a result of AI still being bad at telling the prompter "no". Not only because it will blindly reproduce what you tell it to while writing code without pushing back on assumptions without asking, but because it will often blindly accept an implementation approach while reviewing.
I suspect this is a hard problem, because if AI stops listening at the wrong time it can be a massive inconvenience.
I have noticed that AI is slowly getting better at pushing back on different types of things each time the frontier models get better though. I've also noticed on reviews that it will tend to hallucinate or nitpick around the problem. I assume it sees something wrong there, starts generating output, and points out something different there instead because there is pressure to be both agreeable and helpful, which are not always compatible.
I think it is getting better, but it can't always see the forest for the trees.
1) Document what's there, not the diff. Documentation of how code was removed or changed to fix a bug or add a feature is not useful and difficult to maintain; documentation should explain how code works now.
2) Documentation should live close to the source as possible. Prefer line based comments and standardized function documentation. Top-level sweeping architectural essays are not maintainable for every change.
The last will depend on your codebase. It CAN be very useful to have a human-readable spec documented for the entire program and have it updated when anything changes. But the key is again, you're CHANGING it every time. If you add a whole new disconnected documentation file it should set off alarm bells; nothing in one system is truly disconnected.
It makes it hard to pick apart hallucinations from the miscommunications and disagreements. Picking apart every single point and treating it with the same tact you have to treat human output with, while still accounting for the fact that it could be a hallucination, takes an extremely skewed amount of effort compared to the effort of sending someone AI output. The worst part is, it's probably going to be pasted right back into the LLM chat box.
It's astonishingly bad form to send someone AI output, and this is only one of the reasons.
I really don't see the harm in using them this way that can't also be said about traditional search engines. Search engines already use algorithms, it's just swapping out the algorithm and interface. Search engines can bias our understanding of anything as much as any LLM, assuming you attempt to actually verify information you get from an LLM.
I'm of the opinion that if you think LLMs are bad without exception, you should either question how we use technology at all or question this idea that they are impossible to use responsibly. However I do acknowledge that people criticize LLMs while justifying their usage, and I could just be doing the same thing.
I don't find that this requires discipline. AI code simply requires code review the same as anything else. I don't feel the need to let AI code in unchecked in the same way I don't feel the need to go to my pull request page one day and gleefully hit approve and merge on all of them without checking anything.
It repeats like this predictably. Even though it changes, the way in which it changes is also predictable. Their repetition and predictability make prime numbers a pattern.
Out of the fundamental pattern of prime numbers, higher-level patterns also appear, and studying these patterns is a whole branch of math. You can find all kinds of visualizations of these patterns, including ones linked in this thread.
It's not that you're seeing a pattern that's not there, it's that you're seeing a pattern that gradually becomes infinitely complex.
It's the type of thing you might add to a long checklist of things to make sure you do (or don't do) in an MR template that quickly becomes difficult, if not impossible, for MR authors and especially reviewers to reliably follow.
Tests is another example - you can check that coverage doesn't slip over time, but not that every change is tested. And a human can maybe remember to check if there are tests, even if there are good tests, even if there are tests for every change if coverage tools are well integrated in your system, but not if every change is tested well, and not reliably.
AIs are great at sorting through lots of data to check for errors that a human would miss. Letting it add MR review comments, not letting it make any changes it wants, would allow for a human to provide checks and balances.
So I like the idea, I'm not sure how I feel about limiting it to docs or letting it write changes itself.
I will still say though, I have not actually had this happen to me yet with all the years of using hooks. Generally when I'm fetching when X prop changes, it's not in response to functions or objects, and I guess if it's ever happened it's been fixed and never broke or hasn't caused problems.
Not to say it isn't an issue - it is - but the number and degree of issues I saw with lifecycle functions was much worse. That was with a less experienced team, so it could just be bias.
If your parent component doesn't need the optimization, you don't use it. If it does need it, your intention for using useMemo and useCallback us obvious. It doesn't make your code more confusing inherently.
The article paints it as this odd way of optimizing the component tree that creates an invisible link between the parent and child - but it's the way to prevent unnecessary renders, and for that reason I think it's pretty self-documenting. If I'm using useMemo and useCallback, it's because I am optimizing renders.
At worst it's unnecessary - which is the point of the article - but I suppose I don't care as much about having unnecessary calls to useMemo and useCallback and that's the crux of it. Even if it's not impacting my renders now, it could in the future, and I don't think it comes at much cost.
I don't think it's an egregious level of indirection either. You're moving your callbacks to the top of the same function where all of your state and props are already.
I maintained a Javascript project that used Make and it just turned into a mess. We simply changed all of our `make some-job` jobs into `./scripts/some-job.sh` and not only was the code much nicer, less experienced developers were suddenly more comfortable making changes to scripts. We didn't really need Make to figure out when to rebuild anything, all of our tools already had caching.
If a client wants to know "why is this going to take so long?" I can list the unknowns and third-party touch points, which are always things that make tasks take longer, but then they'll wonder why those are going to make it take longer. From there it's a challenge to communicate how unknowns are part of every project, how they are a good indicator of the risk of a task, and how there are some things you just won't know until you start work on a task in earnest.
Doesn't seem to matter how much detail I go into, it always comes back to "but I thought this would be easy."
The best I can come up with is to educate clients on what bad estimation looks like (Did they come right back with a fixed estimate for your type of project? Are they even asking questions?), hope they come back after getting different estimates with the exact red flags I warned them about, and then maintaining client trust by any means necessary so that when I say something is going to take a certain amount of time they know I'm not exaggerating.
AI struggles with knowledge from after its training date (so it can't help very well for anything relating to new versions of libraries) and often just generally gets things wrong or comes up with suboptimal answers. It's still only optimized to create answers that look correct, after all.
With these problems, someone on the team still needs to understand or be able to figure out what's going on. And dangit if it isn't getting hard to hire for that.
And the day that AI can actually replace the work of junior devs is just going to cause more complications for the software industry. Who will get the experience to become senior devs? Who will direct them? And even if those people also get replaced eventually, we will still probably have more awkward inbetween times with their own problems.
Can't say it's not convenient, but no use pretending the challenges don't exist.