The day the machines took the fun away (AI impressions, part 4 of 5)

This is the fourth part of the series “Impressions of Our Current AI Usage”, as outlined by the introduction article.

The title of this blog entry is also a continuation of an earlier article I wrote about AI advancements in computer gaming, eight years ago.

And if you are inclined to read words out “loud in your head”, you might read it in Trent Reznor’s voice this time.

There is something weird about human’s sense of achievement. Things seem to be “worth” more when they are harder to reproduce. That’s why we value live music over recordings, idolize top athletes and install examinations and tests to filter for official positions.

In the world of software development, the entry bar hung low for a decade now. Gone were the days of rigorous academic training and selection for a degree. If you wanted to go the freelance route, a decent notebook was all it took to be equipped for the job. After that, you could turn electricity and coffee into source code and source code into money.

The reason to enter the field of programming are manyfold, but two main drivers are common: Passion and money. Let’s put money aside and concentrate on the passion aspect: Many programmers love what they do. They even do it for free, in their spare time. The process of creating source code is a deeply rewarding activity for them. It’s not the finished result that “achieves” something, it’s the journey towards it.

I hope you can easily see the similarity to other mainly passion-driven activities like making music or other forms of art, athletic endeavours like mountain-climbing or scientific discoveries. You probably have a hobby yourself that you are passionate about.

Now imagine that somebody automates the journey. You don’t need to climb a mountain, you can just take the elevator. It’s faster, more convenient – and boring. You don’t need to actually play the guitar, you just need to hold it and it plays the most amazing solos itself. And you don’t need to sing, your voice will be autotuned correctly. You’ll be an amazing musician – like everybody else.

When you automate the journey part of an activity, only the chore parts remain to be done. You still need to prepare for thin air on top of the mountain and no autotune will correct your actual song text, so you still need to learn it.

In software development, creating source code is the journey part of the work. There are many supporting activities that need to be done for the journey to be successful on the long run. Things like modelling, planning iterations, bookkeeping the iterations, code review, functional review and manual testing are only some things that still need to be done, regardless of who actually programs. If you can alternate between the activities and have a suitable chore-passion-balance, things feel natural. If only the chore part is up to you, you are the assistant to the machine.

The problem is, that the support work is still necessary. For a short time, you can live without it, but things will inevitably fall apart without proper management and housekeeping. In larger software development teams, these roles are officially assigned to additional team members, but in reality, everybody needs to participate a bit or the process fails.

So why don’t we focus on the chore parts to be automated? There are attempts and the AI is getting better in that regard. But code creation is by far the easiest activity a machine can learn. It produces an immediately digestable result, follows clear rules and can be verified on correctness in multiple ways. Most of the accompanying work is more ephemeral, leaves less of a trace and is not as teachable as “typing out the right sequence of characters really fast”.

In my blog article about computer games eight years ago, I wrote that human players prefer to team up with bots instead of other humans. This only holds true as long as the speed of the game is adapted to human levels – that is, considerably slowed down. If the bots would play only with themselves, they could speed up by several orders of magnitude. And that’s the problem with integrating AI-driven work units into a human-driven choreography: The speedup is not compatible.

In the software development community, there is a legend about a “10X” developer, a human being that is capable of consistenly solving a problem in software ten times faster than the average fellow, without sacrificing quality or longterm viability of the solution. I can attest that these people exist and I’ve seen a few in my career. If you think about AI as just another programmer behind a chat window, it’s more like a 1000X developer (not to be confused with a hundred 10X developers, a whole other bunch of problems!). There is literally nobody human on this planet that can even closely compete with the speed of an AI agent (unless you slow it down by artificial hurdles).

So, looking at the situation from a money viewpoint, the situation is clear: One source of code can provide 1x to 10x product in a given timeframe, while the other source delivers a hundred times more. Both cost roughly the same. But by buying “passion-free” code, the money-driven decider produces some long-term problems that will lead to diminishing returns:

  • AI code is looped back into the training set. So it will reinforce its own idioms, good and bad, just by multiplying them hundredfold into the existing world code base.
  • If AI code prevented a human developer from nurturing her or his passion, it stunts the human creativity pool and leads to a bleaker learning set.
  • The higher the AI code jenga tower is built, the less possible it will be for human developers to interact with it. Relying on AI will be a self-fulfilling prophecy with a ever-shrinking escape window.

To come to a conclusion here: I like to call AI-generated code “passion-free”. And I think that we concentrate too hard on the two questions “can it be done with AI?” and “will it cost less with AI?” and miss the opportunity for a third question that I find important, too: “will it make our lives more fun to do it with AI?

You heard it here first: Stay clear of Always-Updating Software

Depending on who you ask, I would be described as one of the most laid-back, laissez-faire people around, or a dangerously megalomaniac, unrealiable weirdo [Author’s Note: this would lead us astray], and so in terms of what-software-to-use, I would consider most people as the world-leading expert in what works best for them personally.

However, one pattern seems to grind my gears, and while I don’t feel that the Schneide Blog is the best place for overbearing rants based on minor inconveniences, I still recognize a pattern that might be worrying because it is, at least, getting more and more common.

There is some software that is ALWAYS, whenever you start it, surprising you with a software update. Sometimes it is forced upon you, sometimes with sleazy sleights of hand, sometimes you even have the right to have a say in that matter, but nevertheless, it’s ALWAYS. Might not be numerical-always, but still noone on Polymarket would bet against you, so, it’s ALWAYS.

In case you would’t know what software I am talking about – I can give you several names from the top of my head – but you probably know lots of examples on your own 🙂

My core message is, that currently, these scream: “I will bring you harm!”

What is going on with software, having a need to constantly disturb my workflow – a thing that is holy for any serious software developer?
(a) maybe the border-radius of the third panel in the About… dialog was slightly off, and the application shutdown could be improved about 200-300µs.
(b) they are now relying purely on AI to write their most critical core features, with no sensitivity for security whatsoever.

And while I can totally understand (a), in current times you should be honest to endorse – unless you know better – it must be (b).

I, myself, am sometimes willing to recognize that I am not the most risk-averse human in the history of the world, maybe ever; and you probably really are more of an expert of what is good for you than my opinion would count; so, I also use some of these regularly. So, do your own what-could-possibly-go-wrong-gambles, but it is our job to at least feel smart about it when shit is going down (in hindsight, naturally).

Point is, I _could_ be bothered to check the release notes of any of these before any update. But because their move is “we demand on this urgency”, and my thought is “I’m in the process of saving my customer’s life (again)”, I will rarely do that, and unless they communicate better, I think there needs to be a rightful place to call these dangerously megalomaniac, unreliable weirdos out.

We Don’t Program Anymore, We Manage Programming (AI impressions, part 3 of 5)

This is the third part of the series “Impressions of Our Current AI Usage”, as outlined by the introduction article.

In the early years of my career, there was a sudden increase in books about management in the technological fields, especially software development. I didn’t make the connection then, but it was right around the time when the first generation of academically educated software developers were senior enough to climb the corporate ladder one step further and become middle managers. Authors like Tom DeMarco and Timothy Lister wrote books that we discussed fiercly, because their propositions clashed with our observed reality of commercial software development.

“Why are our managers so bad at their job?” we asked. Don’t they see the obvious problems that they themselves created? What we didn’t get was that those managers were very experienced developers, but absolute beginners in their new job – leading people that develop instead of developing things themselves. They knew exactly how they would solve the technical problems, but were forced to concentrate on the very untechnical problems of people under their supervision. Nothing in their previous career prepared them for the challenges that “dealing with people problems” would impose upon them.

I personally know several senior developers that turned down (or reverted) a promotion to a management position, because they might gain some money and status, but lost all the things they were passionate about and good at. Working hard to create the environment where others can have the fun you would want to have yourself, is not the most rewarding job in the world. I fully understand them. And I say that as the founder and boss of a software development company. I’ve found my balance between being a manager and a developer, but it’s a constant negotiation.

The premise of our job as software developer was that customers tell us what they want and we describe it to the computer. In essence, we were translators between the worlds of humans and machines, right down to the languages: Some languages for human interaction, others for machine interaction. Because the computer was dumb as a rock, we needed to craft the solution with immaculate precision and in great detail. If anybody asks why software development took so long and was so demanding, imagine explaining quantum field theory to a first grader, so that the child can work in a laboratory among experienced physicists without screwing everything up.

And now, there is artificial intelligence (currently in the form of LLM-based agents) that produces working source code if prompted roughly right. Back in my days, we would call this role a “junior developer”. Which transforms our role to that of a manager: We bring the requirements from the customer, sketch a solution with our senior developers and architects (in the best case, this is also us) and explain it in necessary detail to the junior developers. Then we wait for them to translate our vision for the computer, review the result and iterate as long as necessary.

The only advantage of this scenario in comparison to the same role a decade ago is that the current junior developers aren’t human anymore. So while we need all the skills a capable manager should have, we don’t have to deal with different personalities and human problems in the workplace.
Except that LLMs tend to exhibit the worst work personality types (charming overconfident dazzlers) and are as ruthless and negligent as human junior developers in their “early ability – peak stupidity” phase. As their manager, you can work with human junior developers on their character journey, using the tools from the “people problems” part of your role, while you can only hope for the next version of LLMs to be more pleasant to deal with.
So, as middle managers between the customer and the juniors, we don’t have to deal with “soft topics” anymore. But we have to endure their effects (good and bad) daily. We are “promoted” to be highly ineffectual managers that supervise a bunch of knowledgable, but otherwise clueless juniors. That’s more or less the experience of previous senior developers that became managers and found themselves overwhelmed and underjoyed. The problem is that our new machine-based junior developers are so fast with their work that we can’t replace them with humans and expect similar performance. And the classic “instruct, oversee, review”-cycle that middle managers go through again and again is sped up from days or weeks to minutes. Which leaves virtually no leeway for typical management activities that still run on human speed and require time.

My hope is that managing AI agents requires a totally different skillset than managing human junior developers. Because otherwise, I can attest most of us experienced developers a pronounced inability and unwillingness to be effective in this new role. And I don’t want to imagine a world where most software development is done by poorly managed AI agents while their managers act and feel like fish out of the water.

AI Code Won’t Be for Humans Much Longer (AI impressions, part 2 of 5)

This is the second part of the series “Impressions of Our Current AI Usage”, as outlined by the introduction article.

In the first years of software development, the word “source code” didn’t exist, because code was just that: encoded machine instructions. How they were encoded changed rapidely, from flipping bits in the RAM directly by mechanical switches over feeding paper tapes with punched holes to magnetic storage. But for a long time, we worked with none or little abstraction over the actual machine code. I remember assembler code listings that had two columns of text: the first column for the computer, the second one just translating the first column into human-readable text.
And even with this little bit of clarification what the code actually does, we already needed additional software that took our source code and translated it for the machine.
With the adoption of higher-level programming languages, the additional software stack grew in depth until the distance between the source code and the actual machine instructions was big enough to warrant an intermediate layer of representation. Programming languages like Java or C# put a “byte-code layer” between our textual source code and the binary machine code. The machine we program against is no longer a real computer, but a “virtual machine” or in better words, a model of a machine. As long as we write source code that works correct with the model, we can assume that all the translation layers will find a way to run it correctly on the real computing substrate.
We are used to this kind of programming. We describe our goals using the machine model and a sophisticated machinery of software and hardware parts make it happen.

Forward to today and we use artificial intelligence (or inference using another kind of “model”) to produce source code in our favorite programming languages by describing our goals in even broader terms than before. We might mistake our prompts for natural language and think that we are able to produce source code by just saying what we want.

The question that poses itself nearly instantly is: If we invented a device that transforms natural language into machine behaviour from scratch today, would we include all the intermediate layers into its inner works? Is it really a good idea to transform natural language into higher-level source code, compile the source code into byte code and do all the weird magic to come up with a sequence of machine instructions that resemble the byte code? Isn’t it more efficient to teach the inference how the actual machine works and let it program directly?
Or, asking from the other side, who is the target audience of the generated source code if nobody reads it and the compiler only parses it once? Why does the inference invent all the variable and method names when the compiler throws them away again in the first step of its processing? Of course, right now the inference only imitates our way of working. But we work like we do because we write source code for other humans. If the human at the helm can’t read any layer of code anyway, why not jump directly to the most obscure representation of code and skip all the readability requirements?

As soon as the inference doesn’t imitate but actually learns about the target computing substrate, it will produce working code that is undecipherable for human readers, but optimal for the machine. (If you want to experience this effect in a tiny dose, I encourage you to play the “TIS-100” programming game). And because most inference users don’t need the readable code anyway, they won’t miss anything and get faster solutions with less hassle.

So my guess is that today’s source code will be a dying art, invented for humans and ignored by the machines because it doesn’t provide anything useful for them. The source code of the future will be less readable, more enigmatic and probably more efficient for the machine. Which means that human intervention or even just participation in the software production process will become more cumbersome and therefore even more limited.

My sorrow is that this distancing of the programming process from actual human oversight might provide a hard depedency on inference work alone. It would mean that humans aren’t just scales slower than the inference, but actually incapable of doing its work by hand anymore.

Computing gets fuzzy again (AI impressions, part 1 of 5)

This is the first part of the series “Impressions of Our Current AI Usage”, as outlined by the introduction article.

In the early days of computing, the mechanism that actually works on the data often was an analog technical device that had a certain kind of fuzzyness to it. Think about paper tape with punched holes as longterm storage: If the paper feeder was not aligned with the distance between the holes, there might be spurious variations in the code. Or, a real possibility from my own childhood: You could store digital data on music tape, an inherently analog storage medium. If the loading process succeeded relied on a mixture of patience, delicate handling, room temperature and luck. Most computing devices had specific analog/digital conversion gateways for the periphery, for the display (a very mechanical cathode ray monitor) and even for their own calculation units. The foundation we built our digital world on was influenced by sunshine, moisture, electrical isolation and lots of other factors that could influence the results. I remember a story about the early mainframe computers where a specific bug only appeared if somebody stepped on the physical floor tile where the cables ran beneath. The pressure change altered the physical properties of the cables which resulted in transmission errors.
Over the years, the physical aspects of computing slowly went away or at least faded into the background. We no longer joked about “cosmic ray errors” because the computing substrate was reliable enough to produce the same result regardless of environmental influences. The world got repeatable and therefore, predictable. We got comfortable with machines that were dumb, but reliable. If they had learnt a functionality, they could repeat it virtually forever, without the slightest variation. We had the precision of a nanosecond clockwork and the determinism of a written story that plays out the same every time it is read.

In the early 1990s, there was the first attempt to soften this black-or-white logic fabric up again. The term “fuzzy logic” was all the hype for a few years. Products like cameras, coffee machines, toasters and even water boilers were marketed as “enhanced by fuzzy logic”. How exactly the coffee got better by miniscule variations in the production process was up to your imagination. The core belief of fuzzy logic was that if we express a formula or algorithm by categorized terms instead of numbers, we could bridge the gap between “gut feeling” and digital mathematics.

In my opinion, the same thing happens again with artificial intelligence as the fuzzy component. I doubt that it disappears as thoroughly as fuzzy logic vanished, but the core belief seems to be the same. If you describe a problem in layman’s terms to an “inference”, it finds a solution that appears to be acceptable. If you describe the same problem again tomorrow, the solution might vary in detail or even in grand concept. What works today might not work anymore tomorrow or work even better. The quality of results rely on “the environment” again, not only on the input. The operating units of computing cease to be deterministic again. Computing gets fuzzy once again.

There are some immediate problems that I see with this approach:

  1. Every quality promise comes with severe limitations: The machine will work as expected today, but it is unclear if that extends very far into the future. The current results vary a bit, but might vary tremendously going forward. If the inference unit isn’t included into the product, it might not work anymore soon. Or it works noticeably different from now.
  2. The machine might change its personality on a whim. This is a problem already with encompassing updates every now and then. My smartphone itself stays the same, but the graphical presentation, usage paths and functionality changes over the course of months, if not weeks. In a world where we are used that a stone acts like a stone, a kitchen timer stays a kitchen timer and a text editor doesn’t turn into an e-mail client, we begin to lose that certainty. Our digital assistants begin to have “phases” with decreased alignment to our use cases. Or, expressed as a positive, we can hope that our digital assistants get to know us better and tune themselves in to us.
  3. We enter a world with limited transferability. One benefit of strict specifications is interchangeability. If you change one capacitor in music electronics, the sound changes (or so they claim). If you change one transistor in a digital circuit, the result stays exactly the same, because the change doesn’t cause enough variance to toggle from “black” to “white”. If the building blocks if your system are less specified digital entities like inference providers, you can’t exchange one against another without possibly altering the system’s behaviour in a noticeable way. This makes the reproducability of an equal system with slightly different components more of an adventure. You just don’t know beforehands that it will work.

There are probably more problems and maybe a lot more advantages to this approach than I can fit into one blog post. My main point is that we layered a strict, digital computing substrate on a messy, analog electronics layer and now put another layer of blurry looseness on top of it. Building future systems on this level might feel like engineering the analog systems of the past. I find it interesting (and ironic) that we try this approach right the moment when the last analog technology heroes step back and take their expertise with them.

Impressions of Our Current AI Usage (part 0 of 5)

There is a lot of hype, noise, love and opinion about the use of artificial intelligence (in all its different forms) in software development. Of course, similar disturbances happen in other markets and academic fields at the same time, but I’m not qualified enough to participate in discussions there.

I feel confident enough to share my impressions on our current usage patterns of AI here. You probably recognize the amount of limitations I put into my statement. The usage patterns evolve quick and still quite radical. I’m no “AI native”, so all I say are just impressions from a certain distance. But I felt confident enough in software engineering for at least 25 years to teach it to the next generations of developers. So I know where we were when it all started.

My impressions will be described in detail in five blog posts, each discussing one specific topic. This is the starting post that introduces the headlines of the following articles, but won’t detail them. If you want to react and comment on a topic, please attach it to the matching blog post so we can keep the discussion on point. I invite you to think along, starting with the headline statements. My thoughts are worthless without your thoughts enriching them with your knowledge and experience.

Let’s have a look at the five impressions:

  1. Computing gets fuzzy again. The components of software systems were never sharply defined, but with AI they tend to act like analog components, having bad days and noisy episodes and all.
  2. Source code gets obscure again. As soon as the AI surpasses the imitation stage of human-written code, we won’t be able to read the generated source code anymore – if the AI bothers to generate source code at all and doesn’t leap to machine code directly.
  3. Software developers don’t create software anymore, they manage and lead software creators. This was the fate of the “senior developer promoted to middle management” all the time, but at least it was humans to lead and manage and not a people-pleasing machine.
  4. We delegate the scalable and fun part of our work to AI. The infamous “10X developer” is now a “1000X AI developer”, but the tedious rest of the work (that exists and makes all the long-term difference) is still up to humans.
  5. The means of production are centralized again. Software development was a profession with incredibly low entry bar (a notebook and a coffee). The actual difference was the skill of the human that did the (mostly intellectual) work. If we all use the same AI (created and provided by infrastructure no single person could just copy), the skill difference will be much smaller and we tend to be interchangeable “workers”.

I don’t expect you to understand my thoughts by just two sentences alone, so stay tuned for the elaborate explanation in the topic-based blog posts of this series.

Topic 1 and 2 focus on technical aspects of software development. Topics 3 and 4 have the remaining human developer in mind, gauging her or his well-being and the skills needed to master a normal workday. Topic 5 broadens the view to economic and even political implications of the changes.

Topic 5 is where I might be wrong the most, because I lack the experience of living through severe changes on the scale that my anticipated changes operate on. I’m not a historian, so I’ll talk about things I only have wikipedia-level knowledge about. I hope that the thoughts are still useful and somebody can provide more content on the topic.

The topic-based blog entries are published in the next weeks or months. I will link them in the list above as soon as they are online. I really appreciate your thoughts, in the form of your own blog entry or a comment.