A good question might be: what do I want to be ? A good prompter ? It's like someone who used to bee a good chef but is now good at ordering at uber eats. Even for a junior: being a good prompter may not be enough.
We tend to think that we make a program, but (writing) the program also makes us what we are. It is what we do that defines what we are. "I think, therefore I am".
I don't see a career path for a prompter. I don't see the benefit for an organization to rely on people who don't understand what they do nor how the programs that keep the organization running works.
That being said, "the man and the machine" can be a powerful combination, like when we drive a motorbike. For me the cooperation with a LLM could work like this: if there is 50 features I write the code for 25 of them and write stubs (classes, methods) for the 25 others, with comments that will be the prompt. The AI audits what I write, gives suggestion, find blind spots and learn best practices from my code. Then I do the same kind of review on the generated code and the AI learns from my review. An AI can even, with luck, suggest a completely new way to solve a problem (see AlphaGo vs Lee Sedol move#37 in game#2) and then I learn something.
Working like that will make me better at reading code (after all Linus spend a lot of time in reading code, it is a good skill to have) while the AI gets better as well. I don't delegate everything and keep practicing, I keep myself up to date, the AI learns from me and I get peer review from the AI. And the codebase does not become a mess (=technical debt) that only another AI can maintain while token prices increases.
Prompting is an intermediate situation at best anyway. I think the most lucrative AI field going forward is going to be liability litigation since there will be only a small handful of AI companies, each the size of small nation states, who will need to be held accountable for what they unleash.
Don't you think that AI hate will limit the general use and then revenues so it will slow down by itself while the niche (AlphaFold for instance) will remains ?
Origins of AI hate:
* "my boss wants me to use AI but he does not understand my job nor how AI works"
* "AI will kill all of us"
* "AI will destroy my job (or my colleague's job if I use AI better than him)".
* I cannot pay my electricity bills because of AI labs.
* ...
See also the mixed feelings about benefits of AI ("harder to justify" according to Uber COO).
I cannot remember a technology that arose so much hate, and for good reasons given how it is presented. I am tempted to think that AI hate or reasonable skepticism (vs unreasonable propaganda) can, maybe, reduce funding and will keep specialized AI for real problem solving (producing tons a LOC per day is not one of them, I think).
Banking on public sentiment to reduce adoption of a profitable technology could be dangerous. There's also a lot of hate for fossil fuels, gambling, health insurance, etc.
You're right, but fossil fuels industry were well established when people started to criticize them, you can even be against fossil fuels (I am) but locked in a system when your job is 30 miles away from your home without public transports. Even your toothbrush uses fossil fuels. A massive infrastructure has been built around fossil fuels, not easy to dismantle.
For AI it is different, it is just the beginning, leading companies are not even profitable and may never be if the majority hate this technology. VC funding will not last forever and corporate customers will not spend without limit like VC did.
I am not saying that "people are always right", but if an unexpected majority of people hates it, it does not help to keep a business running.
Those are all arguably bad things though? I don't think mob mentality should dictate the policy, that can lead to historically bad outcomes (i.e. fascism) since popular opinion can be manipulated through propaganda, but the criticism of the average person against AI ("they will take our jobs", "it will increase my electric bill", etc) are very valid and should weight on the pace we are developing this technology. AI mostly benefits corporations and capital, not the average person. I like the technology from an engineering standpoint and appreciate it can be a force multiplier, but I also agree with the complaints about it.
I do not think hate alone usually slows things very much if they have economic utility (or people strongly believe they do)
It's the byproducts of hate (usually regulation, but occasionally things like boycotts or PR disasters) that do so. In the absence of those things, they just keep on truckin'
For most people, GPS did not improve sense of direction, spellchecking did not help to write without making mistake, deepl did not help to be better in foreign languages. But replacing a bicycle by a motorcycle forces to acquire new skills without losing any, and we can find many example of symbiosis between "The man and the machine" (Lindbergh wrote a book named "WE"). AI could be something like that, after all it is human knowledge reachable in a conversational and contextual manner.
So AI can be used to learn: "tell me what's wrong in my code, or if it can be improved". I also tend to think that the more we code, the more we give AI valuable piece of knowledge to learn from, the best code it can produce, the less the produced code seems alien. It can be a win/win, all depend on the mindset. I like to code and even if I am skeptical about many aspects of AI I can share the workload with a robot, as an exercise or if the time or budget is constrained.
When I start using a chainsaw or a car I hope it has been tested (!) Without tests before delivery the one who tests is the end user. Disaster for a unreliable chainsaw, very unpleasant for a software.
But you're right, the goal is not to write test but to ensure delivery of a reliable software. However each software is a prototype, something that has never been made before (unlike a manufactured car or chainsaw) so the customer must be ready to some unexpected behaviors when the software is released.
Since tests are often sloppy or does not cover every edge case, I see a real value for GenAI. It also forces to write good spec: very clear about inputs and the invariants for each use case. I think that AI (especially GenAI) should first be a solution to existing problem, lack of tests and good specs is often one of them.
If you write too many preconditions, postconditions, invariants etc. Then you cement your software and you will spend most of your time on the tests rather than on the actual useful software
I agree, easy and much more pleasant. Walk down the street, go into the bookshop (which is by essence a place in 3D, much more pleasant than a screen), search for a book, find it, turn a few pages, chat with the seller or with someone else interested by a book you liked, buy the book you came for, and another one you did not plan to buy, stop somewhere to drink a coffee, open the first few pages, etc... How can a website reproduce this "quality of life" ?? No need to live like during covid and lockdowns. If you live 30 km away from the nearest bookshop (like I did for 4 years) a phone call to check if the book is available and order it if it is not. Never bought anything on amazon (don't want, don't need), and maybe 10 times online in the last 25 years for very specific stuff.
They don't have it, because they've limited shelf space and only stock popular books that are on best-seller lists. The History of Scruggs Biplanes 1907-1919 isn't one of them.
What I dislike about the term "clean" code is that it dismiss objective criteria.
"I did it like that because it's cleaner" is a non sense. A program must be maintenable, efficient, observable, testable, scalable, performant, readable, secured. Each criteria can be objectively measured in a kind of radar diagram and can be maximized as long as it does not sacrifice another criteria. Form follows function.
Even "simple" (from KISS) is too vague, fortunately in the conference "simple made easy" Rich Hickey defines what is simple: not interleaved. simple comes from sin plex, the opposite of con plex. Not always easy to make something simple.
However I don't see anything wrong with SOLID. Separation of concerns is how a modern society or a football team works, and S brings D because specialization involves good relationships ("no man is an island" wrote John Donne
), and D is strongly related to L. I has no drawbacks.
However I don't separate data from business logic anymore (no data access layer). Business logic applies on data, not on objects that hide data. Translating a ER diagram into anemic classes while the DBA do the same in the DB does not have any value and forces to use obstruction pattern like repository. If entity classes have properties and methods (a Plane class that has a 'takeOff' and 'land' methods for instance) it is different but must most backend I see don't implement entity classes that way. Because their classes represent data, not animated concept. Player class with a shoot method might makes sense for a video game, User class with a addComment method for a CRUD app makes less sense to me.
> A program must be maintenable, efficient, observable, testable, scalable, performant, readable, secured.
This is the key that most people miss.
The second thing most people miss is most of the time efficient, scalable, and performant are good enough. Not always, there are no absolutes, but most of the time you can safely compromise those 3 without any problem that the real world will notice. In general maintainable has proven to be the hardest/most expensive, and so clean code is most important (don't confuse with Clean Code as a book or any set of rules puts it). Indeed, observable and testable are just different ways to express maintainable. (the first is you can understand what went wrong, and the second you can ensure your changes don't break something else).
Secure is the final thing I didn't mention. this is becoming more and more important. It may even become more important than maintainable in the future.
> "I did it like that because it's cleaner" is a non sense. A program must be maintenable, efficient, observable, testable, scalable, performant, readable, secured. Each criteria can be objectively measured in a kind of radar diagram and can be maximized as long as it does not sacrifice another criteria. Form follows function.
I don't think it's nonsense. "Cleaner" here is just a different word that falls under your categories of readable and maintainable. More toward readable. Different word, same meaning.
That's a key point. Keeping knowledge and know how inside the company is strategic. For most people GPS did not result in better sense of direction, spellchecking did not help to write without making mistakes, and delegating translation to deepl does help to be better in a foreign languages. I don't see the gain for an individual, a company, a society if a technology reduces the ability to think, do stuff, understand complex problem, working hard at something. Hiring junior also matters, what is boring for a senior dev is useful for a junior, like the "wax on wax off" in Karatekid. Then when the senior dev retired the junior is not junior anymore and the know how is still here. I want to to transfer my knowledge to a junior, not to anthropic or google or openai.
Ideally, working hand in hand with an AI could be like driving a motorcycle vs riding a bicycle. Both are fine, but you go much faster with a motorcycle and you don't lose any ability. But prompting a motorcycle auto-pilot by voice sound a bit stupid and boring. Insane use of energy rarely comes into the equation, which is a bit weird. Personally it is why I am never tempted to use AI. However I see value in AI for finding weakness in a code (inverse of flattery), writing tests with all the edge cases based on specs since tests are often sloppy, asking a fresh view on a very difficult problem. I'd love to hear about the equivalent of move#32 in game 2 (AlphaGo vs Lee Sedol) in a difficult programming task. But I think that massive delegation of code writing is how you lose the knowledge and the know how: what keeps us sharp.
Final word: I asked once a review to claude, the codes involved a db transaction. Nothing complicated, Claude said everything was fine. However the transaction isolation level was not set (I did it on purpose, like if I did not know about isolation levels). He did not ask me if it was my intention to keep the default level. I would have preferred a challenging feedback: why did you chose the default isolation level ? Is it on purpose ? Do you know that the default depend on the db ? Do you know about isolation ? Tell me about the business use case and I'll explain which one would be the best.
I just discovered bunny.net thanks to this post. I'd be happy to move my static websites on bunny.net, but is it possible (like on cloudflare) to map requests to /foo to the foo.html file ? According to what I read on the documentation it is not a edge rule.
virtual thread instead of async/await is a counter example.
Java is more used than C#, they can wait before delivering a new feature (given their leader position) but cannot deliver a flawed implementation that would stay in the language forever. Glad to have virtual threads and the backward compatibility that comes with it instead a Async version of sync methods + async and await keywords all over the code and Task as a return type in my interfaces methods to allow implementations to do non blocking I/O calls if they need.
.NET had green threads (fibers) in its first iteration. They were abandoned because practical use of .NET was also FFI-heavy - WinForms etc - and native code generally doesn't play well with non-native threads. The benefit of async is that it desugars into callbacks with state, which is something that can be easily expressed in terms of the C ABI (which is the de facto interop standard on all mainstream platforms). Which is why you can have async C# code calling into async C++ or Rust code, or for that matter async Python calling into async C#. Given that .NET was historically supposed to be a multi-language runtime, before they went all in on C#, async made a lot of sense.
C# did not ship with async/await, and Java didn't have virtual threads back then. I am specifically referring to the initial choices made in C#'s foundation.
I think that words like "clean code" or "beautiful code" does help juniors to learn best practices of software architecture.
- Junior asks to senior: what did you we use an ORM ?
- senior answers: because it's cleaner.
- junior: ???
I prefer when people are able to define a clear list of objectives:
- maintenable;
- performant, scalable;
- efficient;
- resilient;
- observable;
- testable (and tested);
- secured;
- readable for new devs that come on board.
Each criteria balance the others, and the more we add criteria the more it helps to make good choice when we hesitate. It is also meaningful for people outside of the dev team, we can reach an agreement with the customer so he knows what he pays for.
"maintenable" can be also defined, since a project is mostly in maintenance mode during its lifetime (which means the project is successful, which is good !). The ability to incorporate new features without breaking architecture or even without breaking a single method signature is a good starting point.
Being super careful with abstractions. Here someone wrote something like that: "abstraction often hides how what you want is simple". True, ORM I am looking at you. In most case data should be threaten as first class citizen, it also fosters good collaboration with the DBA.
Thinking beyond "the happy path" without falling in premature optimization is also a challenge. A nice one, once again to it avoids to go head first in implementing a good idea without considering drawbacks.
I also tend to imagine that the one that will work on my code had a very bad day so it must be pleasant to read what I wrote. Comments here and there, locale variable here and there even if they can be avoided, variable naming, etc...
Being selective about frameworks. They are good servant but bad leaders. "Be an engineer, not a frameworker" says an article.
Modular frameworks are worth their weight in gold when compared to "highly opinionated frameworks". I don't mind something that's highly opinionated - and highly opinionated is an excellent trait for a library or tool. That lib/tool likely has a large amount of domain expertise in the particular area it operates in.
When it comes to frameworks - highly opinionated tends to get corrupted into "We have this hammer and suddenly everything looks like a nail" - it doesn't always happen and it doesn't always bite you but when orthodoxies are taken from one domain and applied broadly you run the risk of some of the justifications for that orthodoxy being domain specific and being violated in the wider context.
So, when it comes to frameworks, I like modularity where I have options to plug in a different ORM or persistence integration layer - where I can swap out the router - or the validator - or any other component that proves a poor fit for our problem. It is especially valuable if there are multiple paradigms expressed in alternatives within the framework's ecosystem since you may find a pre-baked tool that mostly works where you can choose an option with shortcomings that are clear and addressable if ever the need arises.
To support maintainability it's very important to fight against NIH-ism, that is a constant danger that can soak up resources at an alarming pace - but it's also important to realize that there are some components that you will greatly benefit from tweaking or taking full ownership of with the most difficult problem being trying to figure out which is which.
I appreciate deeply that your list put maintainability first - that's my opinion as well!
We tend to think that we make a program, but (writing) the program also makes us what we are. It is what we do that defines what we are. "I think, therefore I am".
I don't see a career path for a prompter. I don't see the benefit for an organization to rely on people who don't understand what they do nor how the programs that keep the organization running works.
That being said, "the man and the machine" can be a powerful combination, like when we drive a motorbike. For me the cooperation with a LLM could work like this: if there is 50 features I write the code for 25 of them and write stubs (classes, methods) for the 25 others, with comments that will be the prompt. The AI audits what I write, gives suggestion, find blind spots and learn best practices from my code. Then I do the same kind of review on the generated code and the AI learns from my review. An AI can even, with luck, suggest a completely new way to solve a problem (see AlphaGo vs Lee Sedol move#37 in game#2) and then I learn something.
Working like that will make me better at reading code (after all Linus spend a lot of time in reading code, it is a good skill to have) while the AI gets better as well. I don't delegate everything and keep practicing, I keep myself up to date, the AI learns from me and I get peer review from the AI. And the codebase does not become a mess (=technical debt) that only another AI can maintain while token prices increases.
reply