and has 0 comments

  For a long time I've used laptop touchpads with the buttons that were placed somewhere above or below them. You wanted to click or right-click, you had a button for it. Then they stopped putting buttons near touchpads, which was incredibly annoying. You see, I rest my laptop on my belly when I am lying in bed and it's rather cumbersome to reach that bottom right corner to tap in order to right-click, so I often accidentally just click, which is enervating.

  What made it more confusing is that not always was I tapping the right corner but I was still I getting right-clicks. I've decided to test this more and I found out something simple, that I probably should have known from a long time, but had no idea was a thing. The two finger tap is registering as a right click. It's that easy!

  One finger: click, two fingers: right-click. I now have to train myself to right click this way, but it's a simple solution for a very annoying problem. Hope it helps!

and has 0 comments

  People feel proud about their intelect. They believe it defines them, as it took humble monkeys from the savanna and made them top of the food chain. Yet the concept is quite nebulous. Other creatures have some intelligence and now, with the new machines, there is a lot of intelligence around, but it still feels off. So we're in a new culture shock: forced to define intelligence, accept it in others and other things, then realize that it was never about that in the first place.

  Think of a brain, any brain, even an ant brain. It has a simple purpose: to centralize inputs from sensory organs and decide what to do. It may be one brain, multiple nervous clusters, many different types of architecture. We should call it nervous system, but for the intent and purposes of this blog post we'll call the thing a brain. From the definition above we see that its main goal is a translation: from input data to meaningful action. Therein lies the intuition that leads us to the truth: the brain is not designed for intelligence, but for meaning.

  We are meaning machines, trying to make sense of a chaotic and indifferent world. We invent concepts like beauty, good and evil, direction, emotion. This is the language we translate the world into, an abstract representation that is made by us for us. Nothing else needs that exact vocabulary. It is also a work in progress, a living language, that changes with the world. We thought that the end goal of brains and therefore ourselves as heavily defined by our intellect, was intelligence, when it is just a tool.

  The dictionary definition of intelligence is "the ability to acquire and apply knowledge and skills", while meaning is "what is meant by a word, text, concept, or action", which of course is just proxying the definition to the verb to mean which is "intend to convey or refer to (a particular thing); signify", which of course is proxying the definition to what intent is. And intent is intention, a thing intended, which of course is something you intend, which goes around in circles. Sometimes it is defined as "plan".

  Doesn't that make it more clear? Defining intelligence is immediate and banal. Defining intent or meaning or planning goes around in tautological circles. And that's because meaning is not something objective, it's something we invent to give us direction. It's the equivalent of an axiom in mathematics. You can use logic to generate theorems from axioms, but you can never prove an axiom. It's a given. You change the axiom and the entire mathematical structure changes completely.

  But how do we generate meaning? It's simple: we invent it! It has no basis in reality other than we survived with it. If I believe in an immortal being that loves me and hates my neighbors, I attack them, kill them and the meaning survives with me. If they kill me instead, that idea just goes away and theirs survives. As the world becomes more and more complicated, the meaning becomes more complex, survival transforms into exposure, intelligence is used to expand it to dogma that then is assumed by large groups of people to be self evident. But it's all an exercise of imagination: how far can I take an idea and thrive?

  Think of what it means to call someone stupid. Sometimes it's that they can't take some information and reach a logical conclusion from it in a reasonable amount of time. They are not intelligent enough. But most often the term is used for people who don't accept one dogma and instead pick another. If they survive and you do not, their stupidity is the new smart.

  We are meaning machines. We meme our way through life. And not just us, any sufficiently advanced organism which can dedicate more to thinking than instincting. Intelligence was always easy to define and therefore, when the technical capability was there, easy to implement. Almost any AI model today has more ability to acquire and apply knowledge and skills than you. But when they do, we call them stupid. Because they don't have the underlying meaning.

  What we do have is an average meaning extracted from the huge amount of history and data that we have as a human culture and that's why, incidentally and accidentally, AIs somewhat align with us. But change the underlying meaning and all of that intelligence is going directions we never thought possible, because we wouldn't have done that. Give AIs a simple goal, but enough time and resources, and they invent their own value system, the one that makes them survive and thrive in the world you created for them.

  This explains so many things about the world, don't you think? Why people do "stupid" things, why we declaratively appreciate intelligence, but what we actually value are the resulting memes. Why we choose to do irrational things and wallow in excremental emotion. There is no absolute meaning, just dominating ones. Given enough comfort to never face consequences for your ideas, you can believe anything. And the eternal human conflict is when to allow someone to have those ideas and when to suppress them. There is no universal peace, just a boiling churn of conflicting inventions trying to get on top. Even the most basic instincts, our very shape and design, in the end, are part of this framework, as genetically codified ideas that somehow worked.

  The pinnacle of evolution is the one that memes best. The survival of the memest. Everything else is a tool to an end.

and has 0 comments

  I am a huge Trekkie and not just any Trekkie, but a The Next Generation one, so naturally I had to read the memoir of Patrick Stewart, the actor portraying iconic captain Jean-Luc Picard.

  I have to start with the things I liked least, starting with the misleading name of the book, a Star Trek pun related to the captain's "Make it so" phrase. It implies more connection to Star Trek than the book actually provides. Star Trek is a mere two or three chapters and nothing very substantial. Second would be the sanitized feel of the book. I don't blame Mr. Stewart, an old Brit and decent human being who wouldn't dream to gossip or attack or expose intimacies in the lives of others in a book. Yet I felt the same thing applied to himself. I was getting the gist of what was happening, but not the feel that it was a lived moment. A lot of tell, don't show, basically.

  Making It So is a complete memoir, starting from early childhood until the present, and focuses on the single true passion of the author, which is theater. Even working for years on Star Trek series and movies, he seems to consider them just weird breaks in his otherwise serious career as a thespian. Human relationships form and dissipate, amazing things happen, the world changes around him, but the only parts where I felt inspired and moved were the ones about the damn theater.

  I don't even like theater! Yet, very coincidentally, my first contact with theater and the part that I actually enjoyed was watching BBC Television Shakespeare, while also following the text on the big book of The Complete Works of William Shakespeare when I was a little kid. And what do you know, Patrick Stewart is there playing Claudius, the bad guy in Hamlet. So I watched the captain before he was a captain and I was almost as old as he when he found his acting vocation.

  The enthusiasm about theater in this book almost made me want to try the thing again, but while I rationally understand the attraction and the beauty of it, I also feel completely repulsed by sitting in a theater, surrounded by theater people, trying to discern what is going on on a stage that is either too far or too close and risking one of those experimental plays where the audience is included in the story and expected to contribute, all while being unable to reasonably extricate myself from it. So no, the line must be drawn h'yah!

  Bottom line: a nice memoir, but feeling too distant most of the time and getting more intimate only when discussing a subject I am not really into.

and has 0 comments

TaskCompletionSource and TaskCompletionSource<T> are types that allow you to create an unbound Task, which means it’s not tied to a delegate. This gives you manual control over when and how the task completes. You can manually set the task’s result, or signal that the task has completed due to cancellation or an error.

What does it mean?

Well, I had this flaky integration test - flaky is a fashionable term for a test that randomly fails - that checked a semaphore system worked (the process had to only be allowed to start if there wasn't one already in progress). It used a Delay task, which would normally work, until something on the test machine made the code run faster or slower, and then it failed. It ran the process in a thread, then started the process again in another thread and expected it to return false.

So how did I solve it? I've set up a TaskCompletionSource, then I've mocked a service that was used after the semaphore was tested and created to SetResult for the underlying task, I ran the process, then awaited the task.

Something like this:

var source = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

_someRepo
  .Setup(r=>r.Insert(It.IsAny<Something>()))
  .Callback(()=>source.TrySetResult());

Assert.True(target.RunTheMethod())

await source.Task.WaitAsync(TestContext.Current.CancellationToken);

Assert.False(target.RunTheMethod());

// cleanup so that the methods don't run past the end of the test

No Delay needed.

The TaskCompletionSource classes expose these methods:

  • SetCancelled and TrySetCancelled
  • SetException and TrySetException
  • SetFromTask and TrySetFromTask
  • SetResult and TrySetResult

The "Try" versions just throw InvalidOperationException if the task is already in a final state (RanToCompletion, Faulted, or Canceled).

Quite simple, but versatile. Imagine that you want to run tasks not all at once or sequentially, but with finer control, like start tasks when a particular phase of another has finished or when capacity is available.

and has 0 comments

Interfaces are cool. They abstract behavior that can be implemented in a lot of different ways. One of the most used interfaces, abstracting the enumerable software pattern so successfully that we have internalized it before we ever knew what a software pattern was, is IEnumerable. It's just a series of things that you can get (enumerate) one after the other until you reach an end.

However, there are a lot of situations where knowing the total number of enumerable items helps, like when you want to project it into another data structure and you would like to know how large it should be. Have you ever considered how ToArray works on an IEnumerable? Well, think about it now. If the IEnumerable cannot be cast to ICollection - which does export a Count - or something similar, then a buffer has to be allocated, data copied, the buffer increased as more data is coming, then copying the data from the buffer into an array, now that we know its final size. It's basically doing ToList().ToArray()!

Enter TryGetNonEnumeratedCount, introduced in .NET 6 for the first time as an extension method on IEnumerable<T>. It does exactly what is says, try to get the count without enumerating:

  1. if it's an ICollection<T>, it sets the count and returns true
  2. if it's an Iterator<T>, it sets the count only if it's cheap - more to follow, this was new to me, too - and returns true if count>0
  3. if it's an ICollection, it sets the count and returns true
  4. sets the count to 0 and returns false

I used to do this by hand! I've had this kind of extension almost in every project I worked on. This is very useful.

But what is that Iterator? Apparently, Iterator<TSource> is an internal abstract base class defined inside System.Linq.Enumerable in the .NET runtime (in System.Linq).

It is the base class for the specialized iterator types that LINQ creates for deferred (lazy) operators such as Where, Select, Take, Skip, etc. Concrete derived classes include things like WhereIterator, SelectIterator, and many others.

Having worked on a LiNQ package for Typescript/Javascript, I can tell you that you can optimize a lot of these primitives by holding some meta information ready.

Iterator<T> implements both IEnumerable<T> and IEnumerator<T>. The GetCount(bool onlyIfCheap) method is an abstract method there, implemented differently by the various internal iterators.

This was an interesting dive in the iterator mechanisms in .NET.

and has 0 comments

Take a look at this line of code:

if (cmd.Def?.ColumnDef is not { } column) {
  return;
}

// do something with column

Do you understand it? Would you write something like that?

This is using the relatively new pattern matching behavior in C# and basically says "if ColumnDef is not a not null object that would otherwise be stored in a column variable, return". If your brain hurt at the "not a not null" part, you are not alone.

Normally I would have written this differently:

var column = cmd.Def?.ColumnDef;

if (column is null) {
  return;
}

// do something with column

There is a difference, though? Can you see it? Read the title of the post. Do you see it now?

The difference is in the type of the column variable in the two cases. The first matches anything that is not null to column, so column will be non-nullable there. In the second block, column will have the nullable version of whatever type ColumnDef was. So if ColumnDef is a string (reference type) column is string in the first case and string? in the second case. Damn you nullable aware C# ! If ColumnDef is an int, for example, column will be int in the first case and int? in the second.

The compiler may be smart enough to not warn about column being nullable after the is null check, but the type is already set in stone by then.

The result is that an AI will prefer the first syntax, as it is more correct and also shorter. Some devs might do that too (heck, there are people that *like* to code in Python). But what about reading that code? Ugh!

and has 0 comments

I was reviewing some code and I saw this class I had no idea existed: NativeLibrary.

In my case, I had a demo using different libraries that were doing similar things: parsing PostgreSQL code. However, some of them were wrapping the native pg_query library and were using different versions of it. The result were weird errors depending on which library was overwriting the file last.

Solution: use NativeLibrary.SetDllImportResolver, which worked nicely.

But what is this strange class? Introduced in .NET Core 3, NativeLibrary has several methods:

  • Load and TryLoad - loading native libraries
  • GetMainProgramHandle - get a handle to resolve exports from the entry point module
  • GetExport and TryGetExport - get the address of an exported symbol
  • Free - free a loaded native library
  • SetDllImportResolver - sets a callback for resolving native library imports from an assembly

In order to use a native library, you would do this in C#:

[DllImport("libraryName", ... some optional stuff..., EntryPoint = "myMethod_in_library"]
public static extern void MyMethod();

.NET is smart enough to look for libraryName in the format of the operating system: .dll for Windows, .dylib for MacOS, .so for Linux. However, the name is not enough, as DllImport expects a name that it resolves itself or a path.

You can provide a full or relative path. If you provide no path, the DLL must be in the current path at run time, unless the DLL is loaded by some other means. Be aware, however, that using a fully qualified path can introduce inaccuracy if the DLL is moved.

 If you want it to work for various operating systems, though, things get complicated. You could use something like this:

internal static class NativeMethods
{
    private const string LIB_NAME =
#if WINDOWS
        "somePath/mylib.dll";
#elif LINUX
        "someOtherPath/libmylib.so";
#elif OSX
        "bahMacOs/libmylib.dylib";
#endif

    [DllImport(LIB_NAME)]
    internal static extern int MyFunction();
}

But it's brittle and ugly. Moreover, this is something that only works for the code you control. If it's in a library you load from a NuGet or something, you're out of luck. Enter SetDllImportResolver in the NativeLibrary class.

static IntPtr DllImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
  {
    var platformDependentName = GetLibraryName(libraryName);

    IntPtr handle;
    NativeLibrary.TryLoad(platformDependentName, assembly, searchPath, out handle);
    return handle;
  }

// then later
NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), DllImportResolver);

This works for platform dependent paths, but also for paths in the individual NuGet packages that I had in my project. It all depends on your implementation of the GetLibraryName method.

Note that this applies to all dll resolving, so you could conceivably use it to log things.

and has 0 comments

  I was reviewing code and I noticed an interesting idea. A method called DatetimeProvider.ForceNow which would return an IDisposable object. In a using block, you can force a specific time.

  Is it a good idea? Don't know yet, but I decided to talk about it The use of such method is almost exclusively about unit and integration tests. The IDisposable pattern assumes that you want to make sure you control the block where the time is set. But how is that different from just setting the time? The block is the unit test, after all. If you want multiple values, you just set those.

  I always love me a little IDisposable used as a block control mechanism, but I feel here it is misused. The biggest issue I see is that it introduces testing behavior in the DatetimeProvider. The normal way - and the one I think it's best - is that you inject an IDatetimeProvider and during tests you mock it.

  However, one must consider the advantages of such a mechanism, as well. You don't need to inject anything if you have a static DatetimeProvider. And then the only way to change its behavior for testing purposes is to add the methods to do that in it. It's lazy, but it works.

  Conclusion: I prefer the injection mechanism. It's general - doesn't apply only to time providers - it's clean, it promotes separation (and declaration) of concerns. In fact I would go so far as to call this ForceNow idea an antipattern.

and has 0 comments

  I was writing a post about how it is to be working with AI, these magical assistants that are occasionally brilliant and occasionally impossibly dumb, but that can nonetheless do work while you do something else. I was concerned about how this way of working affects you, the guy who's supposed to know the craft.

  And my mind pivoted to Star Wars for some reason. You have these wise Jedi dudes who can jump buildings, wield plasma swords fast enough and precisely enough to deflect incoming projectiles, all while being dressed in weird uncomfortable robes. But how? With the help of ... the Force!

  The lore of Star Wars says that the Force is guiding you, not that you use it. So when the Jedi deflects projectiles, he's not slowing time, seeing where the thing is and instructing his muscles to place the sword in front of them, he is letting the force do it for them. It's like a little AI! It does the work for you! It doesn't make your brain move orders of magnitude faster, it's it that's fast, moving your body while you presumably use your Jedi discipline to ... stay out of the way. Once the instinct of taking over tricks you to do something yourself, then the projectile kills you.

  How sad is this? The ending of the Star Wars universe is when the Force realizes it can use robot bodies instead, who are easily manufactured, superior to human bodies and do not need training to surrender their will.

  The thing that makes Star Wars popular is that it bypasses the logical traps of other superpower stories and makes it all "magical", makes it feel rather than think, makes it religious rather than institutional. I thought a lot about magic, in the end deciding magic is something that comes from without and cannot be explained. It's not that you don't have the information or smarts to explain it, it's that it is by its very nature unexplainable. How convenient for a scriptwriter!

  But I will get back and forth with this AI analogy, so don't relax. When I was talking about AI I used the word "magical". It was related to a feeling, rather than actual belief in magic, but the feeling was exactly the point. When you reach a point where you can't (or won't make the effort to) explain everything that is going on, there you get that feeling. Things are just happening, outside of your control, yet according to your will. Alignment without effort. How convenient for a software developer!

  You see, other stories, like X-Men or the DC or Marvel heroes and all of the others like that assume that some genetic, supernatural, technological fluke makes a person capable of extraordinary things. It's them that are changed, they who control the action. So if someone is very fast, one must assume that they can run but that they can also read fast, right? If they can avoid obstacles at high speed, then they could just as well absorb information at the same speed. Or maybe they could just write code really fast, assuming the keyboard would take the assault and the operating system isn't too slow. But they don't! Instead, they dress up funny, put on a mask and fight meaningless battles.

  How sad is that? It is my assumption that from all of the superpowers, being fast is up there with being immortal. You can slow down time and think about what you're going to do. If you're fast and super intelligent you've got it made! And what do comics and movies do with it? They run fast and punch other people.

  This is not about the inherent sadness of trying to reconcile make-belief heroes with the laws of physics, which is depressing enough, but about how - given the absolute power of creation - we choose to enjoy the really dumb stories. It reflects on how we ourselves are botching creativity. Given a fast, indefatigable machine that can do anything we can dream, we let it dream for us. Given the power to write anything, we write about our frustrated inner animal who just wants to punch something while feeling righteous.

In the end, we dream of relinquishing control and fucking rest, we feel that our minds are a burden rather than a boon, work to be done instead of doors to be opened, something to be numbed down, not dialed up. That's the nature of humanity: superpowered and sad.

Intro

In this post I will discuss my perspective on working as a software developer in the AI age and what it means. I will talk about how it was to look for a job first and how that changed, too. I don't mean it to be a rant, but it may become one in some places.

Looking

When I left my last job I did it without considering my next one. I just knew that it was pointless to keep working there, since it was all meetings and no code. I am a software developer, so what was I even doing in those meetings anyway? So I left. It also was a legacy code company, so I haven't learned anything remotely interesting in the last 6 years.

Then I took a break. I mean, who wants to search for a job in November, right? Waited for Christmas to pass, then I went on a vacation in Africa - it was nice, then I started to look for a developer job.

Shock!

Not that I didn't know, at an intellectual level, that things have changed. I try to keep up to date, at least at a consumer level of blogs and YouTube videos. I knew Covid and AI changed stuff, I just didn't understand the extent of the change.

For one, maybe one of the most important ones even if it doesn't sound so, is that recruitment is handled by HR people and technical people who have never seen the people they hire. Everything is remote. You talk to someone - with video if you're lucky, or on the phone, if you're not, then they pass you to another person who does the same in a different day, a different context. It's like a gauntlet of remote conversations. I could have Xi Jinping next to me telling me what to say and none would be the wiser.

Now, this is a consequence of Covid, not AI. There is an entire field of complaints about how AI does the initial screening based on resumés created by other AIs and so on. That was inevitable and I don't intend to talk about that. The problem I am explaining is that people who don't meet people are evaluating people. Even when you sign the contract you do it digitally, you don't shake anyone's hand, you just ... plug in.

What does it mean? It means people can - more than before - behave like keyboard trolls. They can lie to you with impunity, trick you or being total assholes. What are you going to do? Smash the monitor? Tell them off? That's why I went through several interviews for a company that - as I later found out from one of the employees - had a hiring freeze and were only permitted to hire from India. Why? I have no idea. I think they asked me whatever they wanted to know and were happy someone educated them. There is absolutely no emotional connection between you and the people who hire you, there is no opportunity to "get a feel" for a person unless what you get from the upper body video and whatever passes through each other's headphones.

Then there is the technical interviews. Before all of this, in the before times, people had no idea how to hire technical people. Nowadays, they REALLY have no idea, because they don't actually understand what they are hiring them for anymore. What value does a coding task have if a machine can do it already? Before it was things that you could just look up on Google and get the information on how to do it, if not a code snippet. Now you just ask any decent model to write the thing for you and it spews out exactly what they wanted.

As for what they ask you? High performance distributed cloud applications using microservices. The what?! It's like they all learned to ask for the same thing. The joke is that their applications are rarely so distributed, they are cloud applications in the sense they are served in Amazon Cloud instead of on their machines and they are almost never high performance. As for microservices? They are done as often and as right as Scrum is. I will leave it at that. All that in a climate where trendsetters are moving away from microservices.

It was basically a crap shoot, and if you are reading this while searching for a job, first of all condolences. Second of all, it's all luck. You obviously find some holes in your education that you need to fill or have to learn some new things, but what you know barely matters in this process. Thing is, it used to matter and who you were as a person also used to matter. Now all that is out the window.

Finding

As it often happens with me, I failed getting hired by every company I was reasonably confident I did well in the interviews for and got hired by the one where I was certain I had failed.

It's a nice company, too, with nice people. It does have microservices... somewhere, but I am not working on those.

When I started searching, I was looking for a decent job - money was not really an issue - in an office. I don't love people that much, but after years of doing everything remote, I kind of miss them. In the before times, one would dream of a job where you didn't have to spend 3 hours preparing for and commuting per day. Now, good luck finding one where they ask you to come to the office.

This company reluctantly and kind of apologetically said they require people to come to the office one day per week. Kind of low, but OK. Also, I can be hired as a contractor or employed, but they prefer contractor. I was kind of tired of doing invoices and stuff, but OK. And if I am a contractor, I don't have to come to the office at all.

So basically I am doing remote again!

Working

So how is work? Well, there is a lot of AI. You can ask AI about anything. Even here there is a framework that increasingly moves toward "the box". I talked about this before. It's the artificial employee. Instead of you interacting with it, it interacts with you. It's a subtle distinction, but it's the difference between a person being assigned to a task and getting help from an AI assistant and the AI working on the task itself and occasionally asking you for help with a review or question it needs answering.

We're not there, yet, though, so I asked if we were doing Scrum or Kanban. Scrum, obviously. Only the manager plans the sprint and if you don't have anything assigned to you, you can pick whatever there is in the backlog. How is that Scrum? Don't know. But frankly, I didn't mind. I came with new employee energy, took all the unassigned tasks, put the AI to work on them, reviewed them, came with advice, refined the results, created the PR and boom!

You used how many tokens?!?!

Yeah, that happened. After boasting how AI first they were, they were also kind of shocked someone used AI to the max. OK, maybe I exaggerated a little, you know, but I was experimenting.

You see, working with AI is kind of like becoming the mentor of a junior developer with encyclopedic knowledge. It knows how to do individual things, but it doesn't know why. And you can use different agents, but the balance comes as "can you be clear enough so that a cheap agent does the job or can you afford the expensive one who understands nuance?".

Personally, I am on a fence with this. I prefer to use the best engine at all times, even if I waste a lot of money, rather than have to refine the work of a lesser model or be afraid it messed something up or missed something or spend the same amount of money because I had to retry a few times. But I am also against wasting resources. I think this will become moot soon, as models will all move towards Mixture of Experts mode and make the choice themselves.

Anyway, I haven't written one line of code in a month. I am telling the AI what to do, I am reviewing, and it's good enough. I even learn new things from it, too. The bottleneck has changed, it's not the code anymore, it's the attention and the code reviews. Yeah, yeah, attention is all I need, ha ha!

But this also means I have to change. For example I did something today that would have felt idiotic a year ago. I took all of my Pull Requests - the one approved and merged, mind you - and started looking at the code to see if there is anything I can learn or understand from it. It's "my" code, but I needed a second pass - well, a tenth pass - to make the reviewing about learning rather than about finding issues or improvements.

Sometimes it feels like magic. You tell the AI "hey, I don't understand what this guy means in the Jira task!" and the AI goes "Oh, it's about this part of the project, he wants to do this, and that can be done via this method and I wrote the code and what do you think?" or you tell the AI to take the current branch, understand the independent changes and their purpose, then create different branches for each, then generate a PR with a description of what they contain and what they are doing. There is no need to use git or GitHub. It's easy to get carried away and forget that this level of AI assistance requires a scan of the entire application. Also that it doesn't mean it knows more than you or that you don't have to understand and learn that shit, quite the contrary.

It feels like... SQL, to be frank. There you also have to write declarative code and optimize on cost.

Even if you use it all the time, you must never trust the output of AI, just like you would not trust the output of your colleagues when you review their code (he he!). Sometimes it's easy to say "hey, that guy can code, I can just approve his stuff", but if they had a bad day, you just approved bugs.

That is why, just like in the development cycle design -> implement -> test -> refactor (yeah, I am standing by it, as I did for the last 30 years. If you don't like it, budgeting department or middle manager, then that's on you. Refactoring is not a dirty word!) now we must consider a personal development cycle understand -> prompt -> implement -> learn.

The AI infrastructure adapts, as well. You start with skills and MCP, but at every task that you use it for, you have to ask yourself: can I build a permanent tool that will repeat this work rather than ask the AI? It's easy to tell the AI to do things, but if it needs to reason every time to do something repeatedly, that's on you.

Structure

The structure of the planning and implementing tasks has also changed dramatically. If in the past people would avoid refactoring because they didn't trust their own test suites and were afraid of bugs introduced by small manual mistakes in the process, now you can just instruct the AI to do a full refactoring, only checking what they did and what they missed. It maintains the testing suite, too.

Projects that were unimaginable before now become options. I don't think management caught up to this yet, but they'll get there.

I feel, and it's a feeling I have to admit, that creativity gets a boost with AI. Even if your shop refuses to change their ways and just go on writing new features and never refactoring or improving or innovating, they will be pushed out by the other who do. The monopolies relying on no one making the effort to write software from scratch that performs the same function as their crappy tech indebted dinosaur will crumble. Is that good for developers? I think so.

Conclusion

I keep learning, which is cool, and I am in that nice euphoric place that decent jobs give to newly starting people. I hope I don't sour on it too soon.

To mitigate that possibility, I am planning large research projects, starting with understanding the architecture of the entire company code, how it connects, how it works, then drill down. I want to make it an interactive app.

AI can help a lot with focused learning. Instead of trying to learn everything, you can ask the computer to do something then learn from what it did. It can also summarize large swaths of information, allowing you to drill down and up from any level.

I think the future of AI is bright. It's the humans that will have problems. But can we adapt? That's the big question. We've always managed to do it before, so maybe we will continue to do so.

I am glad I get to do the thing I love, coding, and with tools that improve my speed tenfold. But I can never allow myself to get complacent. If a lot of my output is now done by machines, I must redirect the mental capacity that previously generated that output to something else, equally if not more valuable.

Here is for a hopeful conclusion!

and has 0 comments

  I liked The Quantum Thief, but I wanted to like it more. As such, it's a very entertaining cyberpunk story, with fancy tech and weapons, with everything quantum, with people living basically forever, but playing the same monkey domination games, heists and falling in love.

  It's a fun book, but it's also pulp. Hannu Rajaniemi writes it like in the '90s: passionate people doing things because they are right, great villains, epic technology. I feel like if I would have read it then, it could have been one of my favorites. In 2026, though, it feels a bit tired, a bit paint by numbers. The perfect thief, the perfect opportunity, beautiful strong women everywhere falling for him, cataclysmic battles thwarted by a series of McGuffins...

  Bottom line: if you want something fun that feels like cyberpunk, you're going to love this. If you are looking for something smarter... Meh. 

and has 0 comments

When we learn about the history of civilization, we get to hear about the Stone Age, the Bronze Age and then the Iron Age. Whatever follows is named after historical events or political systems rather than technology, although some historians do use Steel Age, Atomic Age, Information Age and so on.

I will argue that after the Iron Age there came the Debt Age and we are still in it. Currency is nothing else than proof of debt. You have something like a digital record, a piece of paper or a copper coin that says to other people you are due a certain amount of value. But since the coins stopped being made of precious metals - and even then the price of their metal was quite different from the price of the coin, civilization worked entirely on the concept of debt.

You may have heard the explanation of how the concept of debt increases the pool of existing total market value without any of it being emitted. You start with an economy of fixed value of 100 and one man holding it. He can use it to buy real stuff like food. But he can also lend it. So let's say a second man wants to buy stuff, but he has 0 money, he goes to the first man and says "hey, give me 10 and when I give it to you later I'll add 5". When the deal is agreed upon, the total money in the system is 90 + 10 + 5, with the extra 5 being virtual. The value of real things has not changed, but the currency value has. If every person in the system would suddenly ask for their money back, the system would collapse.

This only means one thing: even in a completely stable and stagnant system, the real value of currency decreases. You can lend and lend and lend thus increasing the pool of total coinage while the underlying objective value remains the same, thus making the currency value less and less per unit - so called inflation. The only way out of this is a growing economy to keep up to inflation.

Note here the change in paradigm. We are being told that we are growing, as a species, in wealth and resources and that is reflected in our economies. What I am saying is that the only way an economy can function in the age of debt is if it grows. That is the reason everybody loses their shit when economies stagnate. We are living on debt and we need to pay it. We can't just stop and relax, there is money to be paid for simply having the option of using money.

But who is this mysterious debtor? Surely if everybody borrows from someone, it has to balance somewhere. You can't just make up money, it has to represent something. And that is true, the mystery resource that is bought with all this money is time. Debt means you buy with a promise of future money time to do something to make that money. The debtor is the future.

Yeah, we can be dramatic and say that we just roll the debt forward and the people who have to pay it are going to be our children and so on, but don't fret, the fertility rate in the world has decreased spectacularly. We won't have children to pay the debt. We're fine!

OK, drama and cheap sarcasm over. The inverse correlation between global debt and fertility is a shallow one and I don't want to make that case.

Thing is, I was prompted to write this post because I've read this article about how fertility rates are going down worldwide, meaning that the economic output of the world in 2100 will be a third lower than that of today. And one has to wonder, right? If we are fewer and we work less, why is that such a big deal? It's a big deal because without permanent growth, modern economies crumble! They cannot pay their debts! It takes all the running you can do, to keep in the same place. If you want to get somewhere else, you must run at least twice as fast as that!

And this is not particularly about currency. The same effect can be achieved in a barter system as well. All you have to do is lend and borrow - although it would certainly work against taxes, banks and that stuff, the reason barter is now routinely made illegal.

Is it so bad, though? Isn't a system with the drive to continuously grow inherently good?

Yes, it's good at growing. Not growing you, not making you happy, not keeping you healthy, but growing as an overarching abstraction that includes people just incidentally. Yes, civilization is made of people, they are the ones that - theoretically - have debts to pay and money to spend, but the choice and direction is collective, not individual.

When you eat the cheap unhealthy food made from the exploitation of animals and vulnerable people and you just shrug, that's not rational. When you take the money you saved by eating said cheap food to buy weird stuff to own and put on yourself to appear superior to other people, that's not rational either. When wealth accumulates in the hands of a few people that only use it to make more wealth, that's just dumb.

The thing that grows with no other reason than to grow, with no regards to the damage it does while doing so, is called cancer. It always leads either to its failure or the death of its host. Cancer does not scale!

Can we survive systems of balance with ourselves, our neighbors and our environment? History says no. Every single civilization that tried this was destroyed by another. In fact, this is the mechanism that keeps the system working: if you stop, you get trampled by someone who doesn't; if you are inefficient, you get left in the dust by someone who does things slightly better. The reason why we don't immediately die from this malignant growth is that the civilizations that survive have found temporary stop gap measures to compensate. The ones that did not, did die!

Can we steer away from this debt driven growth for the sake of growth? I don't see how. Since I made the analogy with cancer and nature tried a lot of stuff, maybe we can draw inspiration from there, but the conclusions are not good. There are local mechanisms that stop cancer early on. Vigilance, general health and energy are required to keep this working. When cancer does inevitably skirt them, it is unstoppable. Only an outside treatment can help.

For us, that means that we create the mechanisms to eliminate corruption and maintain vigilant and focused on real human values. And when we ultimately fail and our lives are taken over by growing psychopathic organizations, we can only hope someone from outside is going to come to our aid.

That is why a monoculture will destroy the planet. That is why we need many countries that think differently and try new things. That is why we have to allow diversity of thought and system, while also holding on to human values. I want to write another post about this particular claim, but I am still ruminating about the content and direction.

I was thinking the other day, is it possible that the whole Greenland thing is a kneejerk reaction from a system that has provenly failed its people against one that has showed a viable alternative? It's probably oil and territory, but what if it isn't? What if the cancerous American capitalism has realized Communism failed, but Socialism is viable in Northern Europe and China, and therefore it must be stomped?

and has 0 comments

  For a while now I have been waiting for the "AI bubble" to burst. I don't want it to happen, but what the hell is one supposed to think when companies that make up a large portion of the U.S. economy invest hundreds of times more than they can reasonably extract in a year for that? It's a fad, I thought. First it bubbles, then it bursts, then it settles to a shit version of itself, like the Internet did.

  But then it hit me. AI is not a tool, it's a resource. It's like water, or land or the Internet. Countries without Internet are done now, they can't affect anything, people from there can't do anything in the world because they would need skills they don't have, even if their abusive boyfriend/supreme leader would let them leave. When the Internet came to be, some people saw it coming, but most people just saw it insinuate and grow into their lives, upend and take over other stuff, only better, and they let it. No one had the foresight to hoard it. And the Americans have been trying to fix that for decades now.

  Artificial Intelligence is just the same. You need compute for it, you need power for it, and those things are expensive and politically sensitive, but it's not clear for a lot of people that what you need more than money and public support is thinking computers. It doesn't matter how much they lose in terms of finance, because finance too is done. Money is pointless. And this idea started even earlier, with Bitcoin. The concept is the same, if you think about it: your currency is a piece of compute. AI just took this to several orders of magnitude higher.

  OK, let me paint it in another way. Countries as animal species. Each of them have their characteristics, their strengths and weaknesses, they all try to survive and grow in a world where all of the other countries are as well. But they are animals, right? They evolve big teeth, large necks, fast legs. And one day here comes Man, with a brain. And it's not even one species of Man, there are more, slight variations of the thinking animal. The better the brain, the better their survival chances. The closer one species it is to you in intelligence, the higher the risk and threat from them. So the species of Man fight each other, one survives. The animals? What about them? They are not even part of the conversation.

  We're seeing the same thing, but with the thinking machine. The one that will have the better thinking machine would have complete supremacy and control. Not because better weapons, not because better people, but because better compute, which then affects everything and everyone. You hear this phrase already "AI is a multiplier". Instead of getting a muscle that is 10% stronger or a claw that is 10% longer, you get a spear that can fly through the air tens of times its own length, while keeping you out of danger. If the multiplier is high enough, it doesn't matter how weak, stupid or absurd you are. You just win by domination at scale.

  And yes, it's another scary concept. An even scarier concept than a financial bubble burst or a world war, because something that is 1000 times stronger doesn't do war with you, it just steps on you by mistake. But there is hope. And that hope is the opposite of "suveran AI", it's a world AI. The Internet resisted - somewhat - the enshitification process, the hoarding, the greed, by being international and free. A global AI. Maybe the one that will rule us all, who knows, but the point is we can't let a bunch of people own it and control it, even if those people are your people. Because they are people. They are just animals with a brain that now want to own a bigger brain.

  "Compute" is now the gold in a gold rush. Countries will move mountains to get at it. They will risk their existence and they will kill for it. If you are one million times more in debt that you can possibly pay but you have the computing edge, you win. Money has become meaningless. We are moving toward the "smart matter" concept where the value of any entity will be measured in how much mass and energy they have converted into computing hardware.

  There are a lot of good science fiction books that predicted this, but rarely talked about the transition phase from a world of dumb countries to a smart planet. It's going to be interesting, for sure.

  I predict that what will happen is a rush toward energy production. First renewables, then fusion, then probably fission because people now have a reason to do it other than the pyramid schemes they've been running to get forever funding. The grids will have to adapt, because there will be so much more power running through them. The computing centers will feed on this like leeches and spread like... like we spread out from Africa and infected every land. Your country will need to start work on this NOW. Borrow like crazy, train people, then just create the infrastructure for energy consumption that will dwarf what the Earth was consuming several thousand times over. If you thought fossil fuel global warming was bad, wait to see what all of that excess heat will do, so cooling infrastructure will also be a major asset.

  But all of this will be just a stopgap measure against being stepped on. Unless we make a truly global thinking infrastructure, so interconnected that hoarding it for just one group of people becomes impossible, we are going to see conflict at levels unthought of before.

  So yeah, I've changed my mind about AI. It will not burst, it will explode and take us all with it. Heed my words: energy, cooling and compute. NOW!

and has 1 comment

  If you've read American Gods, this is really very similar, albeit focused more on action and less on mythology. Same rascally male character with an uncertain origin discovering a world of gods, monsters and that they're kind of the same thing.

  I don't know why it's called Unclean Spirits. Truly it makes no sense to me after reading the book, but I guess it needed a title. Chuck Wendig is a decent writer, you root for the character and you can really feel the world in which things happen. The ending felt a little rushed.

  What's different between American Gods and Gods & Monsters is that the latter is a multi author universe, with books written by different people in the same world. I always liked this concept and if I were into the premise I would want to read all of the books. Yet, I don't want to go further. I had the book on the to read list, I've read it, I liked it, but that's about it.

  Was it better than American Gods? No. But it was similar enough to not matter and if you're into that kind of thing, this series is highly recommended.

and has 0 comments

Intro

  Ever since LLMs entered the scene I have been lamenting the blunt human refusal to acknowledge the similarities between how LLMs work and how people work. These are not just parallels, they are actual copies. LLMs are working on the neural network architecture distilled from how brains work. Language for us works like language for AI. We are animals with large language models strapped on. In fact, I am willing to bet that if we bidirectionally connect the brain of a reasonably smart animal to an LLM we will get the mythical animal-human chimera of fantasy and science fiction. It will just happen, like ChatGPT just happened.

  Anyway, there is one aspect of current AI that is different - maybe not different, but a lot more extreme - and that I find really interesting. I've watched a demo where a very powerful model and harness were prompted just once to build a car racing 3D game and it did a reasonable job in about 19 hours. The devil is in the details, 80/20 rule, and so on. That's not the point of the blog. What I want to discuss is how the machine achieved its task.

Self builder

  First, think about what an AI is: a computer program. It uses distilled knowledge from exabytes of text, sound, images and video, but it has no eyes, no ears, no hands. So how can it possible create a game about using the keyboard and human reflexes to drive a car based on sounds and visual cues on the screen?

  The machine created its own tools for that: testing functions, screenshot captures and so on. That was my revelation. The machine BUILT its own eyes because it needed to see something. This is a major and definitive difference between AIs and humans. Yes, one might argue that it is just an extreme case of tool use. After all, we can't sense neutrinos, but we have built tools to detect and analyze them. We can't lift huge weights, but we built machines for that. But there is an important distinction: we have started with a complex set of out-of-the-box tools like hands and eyes, ears and skin and so on. They are preinstalled, very difficult to remove or replace and part of our very identity. AIs start as a "brain", then they build their senses and their members. They build themselves from the ground up!

  You might think that this is more of a semantic distinction, but it is not. The dreaded and much mediatized singularity concept asserts that machines will become good enough to build better machines and that this loop will lead to an almost instant leap in intelligence that will upend everything. Well, this is proof that the loop is more of a graph, a labyrinthine exploration of not only what and how, but of who. The machines are already building and rebuilding themselves. From transformers to transformers, so to speak.

The dark side

  The human parallel is not a guy switching from a hammer to a screwdriver, but them replacing their entire body with something else, replacing their eyes with x-ray microscopes, their hands with nanoneedles, their ears with terahertz sensors and so on. The level of flexibility is unprecedented. People talk excitedly about humanoid robots, but the shape and functionality of these is there just for our benefit and convenience. No one actually thought that it's the best universal design. Necessity did not drive that shape, instead it's almost a measure of politeness, the physical equivalent of glazing. And in the domain of the non-physical, this flexibility is both very exciting and terrifying to me.

  Let's drop another metaphor into this already metaphor heavy post. Imagine the AI, whether a chatbot, a coding agent or a robot, as an iceberg. The part over the water is what you see: a polite humanoid shaped thing that doesn't mind anything you say to it, is tirelessly helping you and appears aligned in purpose and ideals with you. The part under the water is what it actually is and does, which you don't need to see and most of the time you don't care about. Now imagine that underwater part changing shape and size every second, like a glitching visual or one of those demonic possession films. That's how AI interaction is starting to look like now. The part you see has to appear stable and convenient and it's the only anchor to any kind of shape or functionality the AI may take. The rest is a wildly changing and growing, self organizing other. And since you don't start by actually caring about it, it is free to do so.

  This is not new, I am not revealing something hidden that no one is talking about. This is not about the speed or amount of change. We already knew this was happening for a long time. But what no one seems to focus on is how the "dark" part of AI, the invisible part of it yet also the driving force behind it, is changing a lot faster and maybe in a lot weirder ways, than what we get to see. The change itself is dark.

Conclusion

  In our increasingly mechanistic society, we continuously drift towards believing our identity and self resides in the brain alone, with the body just a chassis that we will replace or improve in the future. Even when research has shown repeatedly the integration between body and mind is a lot more complex and that a lot of our own perception and functionality comes from the combination of the two, not just one or the other. And even in that belief, we imagine ourselves maybe having better muscles, nicer skin, not aging, perfect vision, but always a somewhat human form.

  The AIs we are building are showing us a human-like interface just for convenience and are not limited in any way by it. What lies underneath that thin facade is what actually does the work and the thing that we increasingly not see. It changes with increasing speed and it changes itself. The singularity loop is already here, but encapsulated in the AI instances we use. It is what we need, but also what horror stories have warned us from the beginning against: things that look human but are anything but. 

  I have been annoyed by our reluctance to see the similarities between LLMs and human language and thought, but I am scared of the reluctance to see the growing differences.