and has 0 comments

  On May 8th 1989 the Star Trek: The Next Generation episode "Q Who?" was released. Not only did it feature Jon de Lancie's delicious interpretation of the being Q, but it introduced for the first time the Borg. Now, the concept of the Borg is not that original: a cybernetic race bent on absorbing everything useful and destroying any enemy or obstacle in their path. They were contrasting the liberal individualism of the United Federation of Planets with a hive mind that connected all Borg to the point where they had no identity. At the time their purpose in the series was to inspire terror: they cared not for damage, they felt no fear or pain, had no interest in negotiation or communication and they were unstoppable in their goal of assimilating the Enterprise. And they were terrifying!

  Then they were brought again for the last episode of season 3 and the continuation in the first episode of season 4. That cliffhanger! The episodes had the title "The Best of Both Worlds". Keep that in mind, because I think it hints at the conundrum the Borg represent. 

  I fell in love with the concept of the Borg. The more I thought about it, the more intriguing they became. They exposed the mindless assumptions that most people take for granted because they were drilled into them by parents and the education system from the earliest age. It made me think about my own identity, reflect on the future and direction of humanity and, in the end, forced me to ask the question "Are the Borg really bad?".

  On a very basic social organization level, it seemed like the Borg were the ultimate tyrannical communists, denying the option of individual thought and forcing everyone to work for the collective. But going a bit further with it, one realized that they stood at the intersection of pure communism and pure democracy. There was no actual tyrant forcing people to act against their will, instead there were part of a mind in which all people were represented, to the point where individuality became meaningless at best and detrimental to the whole at worst. The ultimate tyranny was that of the majority, perhaps.

  On a moral level, the forceful absorption of alien races and the destruction of their cultures was abhorrent, but in the Borg philosophy it was liberating people from the burden of individuality, improving the collective, eliminating potential threats and possibly offering each assimilated individual a form of immortality. Many cultures on Earth, including the United States, proceeded on forcing their philosophy on the world in the name of liberty and better lives. Can you imagine a Borg collective that would have absorbed some parts of alien cultures, not destroying the rest, but just slowly infiltrating, using promises of a better life? How ironic would that have been? Give us your tired, your poor, your sick, your dying, your huddled masses yearning to breathe free, the wretched refuse of your teeming shore and will make them Borg and give them new life.

  On a technological level the Borg were supreme. If it weren't for the pesky need to have our heroes prevail, humanity would have stood no chance whatsoever. It was one of the first mainstream TV depictions of cosmic horror, the feeling that comes with the realization the universe is indifferent to your existence and your maximum possible contribution completely insignificant, and I was loving it! But isn't it the same thing with some advanced nations on Earth, acting all mighty and moral while exploiting other nations while keeping them in abject poverty?

  On a philosophical level the Borg were awesome. They adapted to threats, turned adversity into strength, knowledge into power, all the while yearning and actively pursuing the improvement of their species. A fascist vibe, for sure, but isn't fascism so attractive to some people that it brings the hardest fanaticism to the surface? Isn't that the logic of every nation at war? Us against them?

  Were the Borg the ultimate baddies or were they the cruelest satire of our own civilization? It was becoming apparent that in order to make them feel more like enemies and less than mirrors of ourselves the writers of the show were piling up all kind of incongruous defects on the species. The cybernetic appendages were hideous, looked painful and corrupting the beauty of the flesh. Their actions veered from utilitarian to cruel. The Borg drones acted like mindless clumsy robots, uncaringly wasting life after life just to adapt to simple technologies like phaser fire.

  When Seven of Nine was introduced in Voyager, there were some really intriguing explorations of the Borg ethos. After being "liberated" from the collective, Janeway hypocritically offered her the choice to return to being a Borg, and Seven wanted back. Surprised, Janeway revealed that she had no intention whatsoever to honor her promise or the wishes of Seven. Resistance was futile.

  Seven was proud to be Borg: fearless, efficient, ready to adapt to anything and sacrifice everything for her group. If all Borg felt the same, then they were a species of stoic heroes, something that we humans have always honored and aspired to. The irony of freeing someone from a life of selfless service.

  Most other depictions of the Borg in the Star Trek universe were designed to lazily use the template of the "bad guy" in situations were the Borg were either not needed or would have easily won if not nerfed by silly plot holes, but there were a few glimpses of what the Borg could have really been.

  It was obvious that no one was interested in keeping the Borg as a believable threat. The "Borg queen" was introduced to make all attractive qualities of the collective simple consequences of an arbitrary individual, a responsible guilty party and a single point of failure to the entire Borg species. When writers did that, it was clear they didn't understand what the Borg were about, were not interested in exploring them further as mirrors of ourselves and were ready to destroy them with the silly trope of "find the brain, blow it up", the cesspool that all lazy sci-fi ends up in.

  My twelve year old me was full of questions and fantastical ideas after meeting the Borg. I was imagining a parallel universe where Star Trek was all about the Federation trying to hold back the Borg. When Star Trek: Deep Space 9 came about and then the Dominion War, I decried that they could have done that with the Borg instead, exploring and continuously redefining the ideals of humanity on the background of possible assimilation. I still dream of such a franchise. It seems that we always start to do it, but chicken out when it matters most: Star Trek and the Borg, Starship Troopers and the bugs, Stargate and the Goa'uld, Starcraft and the Zerg. We seem incapable of sustaining a prolonged conflict against a species that denies our choice of identity, whether in real life or in fantasy. Wouldn't that be most apropos of modern times?

and has 0 comments

C# 3.0 introduced Object Initializer Syntax which was a game changer for code that created new objects or new collections. Here is a contrived example:

var obj = new ComplexObject
{
    // object initializer
    AnItem = new Item("text1"),
    AnotherItem = new Item("text2"),
    // collection initializer
    RestOfItems = new List<Item>
    {
        new Item("text3"),
        new Item("text4"),
        new Item("text5")
    },
    // indexer initializer
    [0]=new Item("text6"),
    [1]=new Item("text7")
};

Before this syntax was available, the same code would have looked like this:

var obj = new ComplexObject();
obj.AnItem = new Item("text1");
obj.AnotherItem = new Item("text2");
obj.RestOfItems = new List<Item>();
obj.RestOfItems.Add(new Item("text3"));
obj.RestOfItems.Add(new Item("text4"));
obj.RestOfItems.Add(new Item("text5"));
obj[0] = new Item("text6");
obj[2] = new Item("text7");

It's not like the number of lines has changed, but both the writability and readability of the code increase with the new syntax. At least that's why I think. However, outside these very simple scenarios, the feature feels like it's encumbering us or that it is missing something. Imagine you want to only add items to a list based on some condition. You might get a code like this:

var list = new List<Item>
{
    new Item("text1")
};
if (condition) list.Add(new Item("text2"));

We use the initializer for one item, but not for the other. We might as well use Add for both items, then, or use some cumbersome syntax that hurts more than it helps:

var list = new[]
{
    new Item("text1"),
    condition?new Item("text2"):null
}
.Where(i => i != null)
.ToList();

It's such an ugly syntax that Visual Studio doesn't know how to indent it properly. What to do? Software patterns to the rescue! 

Seriously now, people who know me know that I scoff at the general concept of software patterns, but the patterns themselves are useful and in this case, even the conceptual framework that I often deride is useful here. Because we are trying to initialize an object or a collection, which means we are attempting to build it. So why not use a Builder pattern? Here are two versions of the same code, one with extension methods (which can be used everywhere, but might pollute the member list for common objects) and another with an actual builder object created specifically for our purposes (which may simplify usage):

// extension methods
var list = new List<Item>()
    .Adding(new Item("text1"))
    .ConditionalAdding(condition, new Item("text2"));
...
public static class ItemListExtensions
{
    public static List<T> Adding<T>(this List<T> list, T item)
    {
        list.Add(item);
        return list;
    }
    public static List<T> ConditionalAdding<T>(this List<T> list, bool condition, T item)
    {
        if (condition)
        {
            list.Add(item);
        }
        return list;
    }
}

// builder object
var list = new ItemListBuilder()
    .Adding("text1")
    .ConditionalAdding(condition, "text2")
    .Build();
...
public class ItemListBuilder
{
    private readonly List<Item> list;

    public ItemListBuilder()
    {
        list = new List<Item>();
    }

    public ItemListBuilder Adding(string text)
    {
        list.Add(new Item(text));
        return this;
    }

    public ItemListBuilder ConditionalAdding(bool condition, string text)
    {
        if (condition)
        {
            list.Add(new Item(text));
        }
        return this;
    }

    public List<Item> Build()
    {
        return list.ToList();
    }
}

Of course, for just a simple collection with some conditions this might feel like overkill, but try to compare the two versions of the code: the one that uses initializer syntax and then the Add method and the one that declares what it wants to do, step by step. Also note that in the case of the builder object I've taken the liberty of creating methods that only take string parameters then build the list of Item, thus simplifying the syntax and clarifying intent.

I had this situation where I had to map an object to another object by copying some properties into collections and values of some type to other types and so on. The original code was building the output using a top-down approach:

public Output BuildOutput(Input input) {
  var output=new Output();
  BuildFirstPart(output, input);
  BuildSecondPart(output, input);
  ...
  return output;
}

public BuildFirstPart(Output output, Input input) {
  var firstSection = BuildFirstSection(input);
  output.FirstPart=new List<Part> {
    new Part(firstSection)
  };
  if (condition) {
    var secondSection=BuildSeconfSection(input);
    output.FirstPart.Add(new Part(secondSection));
  }
}

And so on and so on. I believe that in this case a fluent design makes the code a lot more readable:

var output = new Output {
  FirstPart = new List<Part>()
    .Adding(BuildFirstSection(input))
    .ConditionalAdding(condition, BuildSecondSection(input),
  SecondPart = ...
};

The "build section" methods would also be inlined and replaced with fluent design methods. In this way the structure of "the output" is clearly shown in a method that declares what it will build and populates the various members of the Output class with simple calculations, the only other methods that the builder needs. A human will understand at a glance what thing it will build, see its structure as a tree of code and be able to go to individual methods to see or change the specific calculation that provides a value.

The point of my post is that sometimes the very out-of-the-box features that help us a lot most of the time end up complicating and obfuscating our code in specific situations. If the code starts to smell, to become unreadable, to make you feel bad for writing it, then stop, think of a better solution, then implement it so that it is the best version for your particular case. Use tools when they are useful and discard them when other solutions might prove more effective.

and has 0 comments

  Man of Two Worlds may be the worst book signed by Frank Herbert that I've ever read. It features that nasty '50s newsroom trope, where single minded egotistical people (sometimes to the point of cruelty) get a pass because they are brilliant and they talk fast (and they own the newspaper). The characters are unsympathetic and rather not interesting, while the ideas in the book are dull and going nowhere. The plot itself is often inconsistent. I do suspect that this is more of a Brian than a Frank book, because none of the themes found in previous Frank Herbert books are found here (if one discounts the awkward depiction of women). Also the tiny Wikipedia page dedicated to the book lists Brian as the main author.

  In short, the story is about a human and an alien merging accidentally and having to work together to get things done. Kind of like the authors were trying to do, huh? The setting is classic '50s sci-fi, with people living on Mars and Venus and going from planet to planet using vehicles that function like normal airlines, only in space. Meanwhile, the aliens are trying to destroy Earth because they fear humans - not sure how that would work since they already live on other planets, and the humans have their own familial issues to resolve - including an uncle with god-like powers but no apparent care about the outcome of anything he does.

  There are many issues with the book that I am not going to go into. I almost did not finish it. However, someone else might enjoy it, so no need to rant in this review. Suffice to say that the book feels insulting when it is not boring, which is most of the time. I don't recommend it.

and has 1 comment

Intro

  Some of the most visited posts on this blog relate to dependency injection in .NET. As you may know, dependency injection has been baked in in ASP.Net almost since the beginning, but it culminated with the MVC framework and the .Net Core rewrite. Dependency injection has been separated into packages from where it can be used everywhere. However, probably because they thought it was such a core concept or maybe because it is code that came along since the days of UnityContainer, the entire mechanism is sealed, internalized and without any hooks on which to add custom code. Which, in my view, is crazy, since dependency injection serves, amongst other things, the purpose of one point of change for class instantiations.

  Now, to be fair, I am not an expert in the design patterns used in dependency injection in the .NET code. There might be some weird way in which you can extend the code that I am unaware of. In that case, please illuminate me. But as far as I went in the code, this is the simplest way I found to insert my own hook into the resolution process. If you just want the code, skip to the end.

Using DI

  First of all, a recap on how to use dependency injection (from scratch) in a console application:

// you need the nuget packages Microsoft.Extensions.DependencyInjection 
// and Microsoft.Extensions.DependencyInjection.Abstractions
using Microsoft.Extensions.DependencyInjection;
...

// create a service collection
var services = new ServiceCollection();
// add the mappings between interface and implementation
services.AddSingleton<ITest, Test>();
// build the provider
var provider = services.BuildServiceProvider();

// get the instance of a service
var test = provider.GetService<ITest>();

  Note that this is a very simplified scenario. For more details, please check Creating a console app with Dependency Injection in .NET Core.

Recommended pattern for DI

  Second of all, a recap of the recommended way of using dependency injection (both from Microsoft and myself) which is... constructor injection. It serves two purposes:

  1. It declares all the dependencies of an object in the constructor. You can rest assured that all you would ever need for that thing to work is there.
  2. When the constructor starts to fill a page you get a strong hint that your class may be doing too many things and you should split it up.

  But then again, there is the "Learn the rules. Master the rules. Break the rules" concept. I've familiarized myself with it before writing this post so that now I can safely break the second part and not master anything before I break stuff. I am talking now about property injection, which is generally (for good reason) frowned upon, but which one may want to use in scenarios adjacent to the functionality of the class, like logging. One of the things that always bothered me is having to declare a logger in every constructor ever, even if in itself a logger does nothing to the functionality of the class.

  So I've had this idea that I would use constructor dependency injection EVERYWHERE, except logging. I would create an ILogger<T> property which would be automatically injected with the correct implementation at resolution time. Only there is a problem: Microsoft's dependency injection does not support property injection or resolution hooks (as far as I could find). So I thought of a solution.

How does it work?

  Third of all, a small recap on how ServiceProvider really works.

  When one does services.BuildServiceProvider() they actually call an extension method that does new ServiceProvider(services, someServiceProviderOptions). Only that constructor is internal, so you can't use it yourself. Then, inside the provider class, the GetService method is using a ConcurrentDictionary of service accessors to get your service. In case the service accessor is not there, the method from the field _createServiceAccessor is going to be used. So my solution: replace the field value with a wrapper that will also execute our own code.

The solution

  Before I show you the code, mind that this applies to .NET 7.0. I guess it will work in most .NET Core versions, but they could change the internal field name or functionality in which case this might break.

  Finally, here is the code:

public static class ServiceProviderExtensions
{
    /// <summary>
    /// Adds a custom handler to be executed after service provider resolves a service
    /// </summary>
    /// <param name="provider">The service provider</param>
    /// <param name="handler">An action receiving the service provider, 
    /// the registered type of the service 
    /// and the actual instance of the service</param>
    /// <returns>the same ServiceProvider</returns>
    public static ServiceProvider AddCustomResolveHandler(this ServiceProvider provider,
                 Action<IServiceProvider, Type, object> handler)
    {
        var field = typeof(ServiceProvider).GetField("_createServiceAccessor",
                        BindingFlags.Instance | BindingFlags.NonPublic);
        var accessor = (Delegate)field.GetValue(provider);
        var newAccessor = (Type type) =>
        {
            Func<object, object> newFunc = (object scope) =>
            {
                var resolver = (Delegate)accessor.DynamicInvoke(new[] { type });
                var resolved = resolver.DynamicInvoke(new[] { scope });
                handler(provider, type, resolved);
                return resolved;
            };
            return newFunc;
        };
        field.SetValue(provider, newAccessor);
        return provider;
    }
}

  As you can see, we take the original accessor delegate and we replace it with a version that runs our own handler immediately after the service has been instantiated.

Populating a Logger property

  And we can use it like this to do property injection now:

static void Main(string[] args)
{
    var services = new ServiceCollection();
    services.AddSingleton<ITest, Test>();
    var provider = services.BuildServiceProvider();
    provider.AddCustomResolveHandler(PopulateLogger);

    var test = (Test)provider.GetService<ITest>();
    Assert.IsNotNull(test.Logger);
}

private static void PopulateLogger(IServiceProvider provider, 
                                    Type type, object service)
{
    if (service is null) return;
    var propInfo = service.GetType().GetProperty("Logger",
                    BindingFlags.Instance|BindingFlags.Public);
    if (propInfo is null) return;
    var expectedType = typeof(ILogger<>).MakeGenericType(service.GetType());
    if (propInfo.PropertyType != expectedType) return;
    var logger = provider.GetService(expectedType);
    propInfo.SetValue(service, logger);
}

  See how I've added the PopulateLogger handler in which I am looking for a property like 

public ILogger<Test> Logger { get; private set; }

  (where the generic type of ILogger is the same as the class) and populate it.

Populating any decorated property

  Of course, this is kind of ugly. If you want to enable property injection, why not use an attribute that makes your intention clear and requires less reflection? Fine. Let's do it like this:

// Add handler
provider.AddCustomResolveHandler(InjectProperties);
...

// the handler populates all properties that are decorated with [Inject]
private static void InjectProperties(IServiceProvider provider, Type type, object service)
{
    if (service is null) return;
    var propInfos = service.GetType()
        .GetProperties(BindingFlags.Instance | BindingFlags.Public)
        .Where(p => p.GetCustomAttribute<InjectAttribute>() != null)
        .ToList();
    foreach (var propInfo in propInfos)
    {
        var instance = provider.GetService(propInfo.PropertyType);
        propInfo.SetValue(service, instance);
    }
}
...

// the attribute class
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class InjectAttribute : Attribute {}

Conclusion

I have demonstrated how to add a custom handler to be executed after any service instance is resolved by the default Microsoft ServiceProvider class, which in turn enables property injection, one point of change to all classes, etc. I once wrote code to wrap any class into a proxy that would trace all property and method calls with their parameters automatically. You can plug that in with the code above, if you so choose.

Be warned that this solution is using reflection to change the functionality of the .NET 7.0 ServiceProvider class and, if the code there changes for some reason, you might need to adapt it to the latest functionality.

If you know of a more elegant way of doing this, please let me know.

Hope it helps!

Bonus

But what about people who really, really, really hate reflection and don't want to use it? What about situations where you have a dependency injection framework running for you, but you have no access to the service provider builder code? Isn't there any solution?

Yes. And No. (sorry, couldn't help myself)

The issue is that ServiceProvider, ServiceCollection and all that jazz are pretty closed up. There is no solution I know of that solved this issue. However... there is one particular point in the dependency injection setup which can be hijacked and that is... the adding of the service descriptors themselves!

You see, when you do ServiceCollection.AddSingleton<Something,Something>, what gets called is yet another extension method, the ServiceCollection itself is nothing but a list of ServiceDescriptor. The Add* extensions methods come from ServiceCollectionServiceExtensions class, which contains a lot of methods that all defer to just three different effects:

  • adding a ServiceDescriptor on a type (so associating an type with a concrete type) with a specific lifetime (transient, scoped or singleton)
  • adding a ServiceDescriptor on an instance (so associating a type with a specific instance of a class), by default singleton
  • adding a ServiceDescriptor on a factory method (so associating a type with a constructor method)

If you think about it, the first two can be translated into the third. In order to instantiate a type using a service provider you do ActivatorUtilities.CreateInstance(provider, type) and a factory method that returns a specific instance of a class is trivial.

So, the solution: just copy paste the contents of ServiceCollectionServiceExtensions and make all of the methods end up in the Add method using a service factory method descriptor. Now instead of using the extensions from Microsoft, you use your class, with the same effect. Next step: replace the provider factory method with a wrapper that also executes stuff.

Since this is a bonus, I let you implement everything except the Add method, which I will provide here:

// original code
private static IServiceCollection Add(
    IServiceCollection collection,
    Type serviceType,
    Func<IServiceProvider, object> implementationFactory,
    ServiceLifetime lifetime)
{
    var descriptor = new ServiceDescriptor(serviceType, implementationFactory, lifetime);
    collection.Add(descriptor);
    return collection;
}

//updated code
private static IServiceCollection Add(
    IServiceCollection collection,
    Type serviceType,
    Func<IServiceProvider, object> implementationFactory,
    ServiceLifetime lifetime)
{
    Func<IServiceProvider, object> factory = (sp)=> {
        var instance = implementationFactory(sp);
        // no stack overflow, please
        if (instance is IDependencyResolver) return instance;
        // look for a registered instance of IDependencyResolver (our own interface)
        var resolver=sp.GetService<IDependencyResolver>();
        // intercept the resolution and replace it with our own 
        return resolver?.Resolve(sp, serviceType, instance) ?? instance;
    };
    var descriptor = new ServiceDescriptor(serviceType, factory, lifetime);
    collection.Add(descriptor);
    return collection;
}

All you have to do is (create the interface and then) register your own implementation of IDependencyResolver and do whatever you want to do in the Resolve method, including the logger instantiation, the inject attribute handling or the wrapping of objects, as above. All without reflection.

The kick here is that you have to make sure you don't use the default Add* methods when you register your services, or this won't work. 

There you have it, bonus content not found on dev.to ;)

and has 0 comments

  Imagine reading a novel about a global pandemic with the background of Irish violence right about when Covid struck and people didn't know how Brexit was going to turn out and what it would do to Irish tensions. That was the best moment to read it. A bit anachronistic, with some pacing issues, The White Plague is still one of Frank Herbert's best.

  After reading the book synopsis, one expects to get a book about a violent global pandemic, but in fact that's just the first quarter of the book. The rest is psychological explorations of people motivations and characters, the ubiquitous Herbert attempts to find a solution to the toxic human organizational structures, analysis of history, violence, religion and philosophy. I mean, it's Herbert!

  A violent "Provo" bombing kills the wife and daughters of a molecular biologist that was in Ireland on vacation. He goes mad and creates a plague to destroy the people who wronged him by killing their women. I can't but smile at the implications, that if a smart educated scientist gets pissed off they could easily cause more damage than the toys and sticks of military people. The theme reminds me of his short story Public Hearing, which explores what happens when immense destructive power can be achieved with little effort by individuals, and how that makes governments - the keepers of peace - obsolete.

  But then there is the larger part of the book that is just the guy walking in the Irish countryside with a priest, a mute child and an IRA member that was actually the one who ordered the bomb that killed his wife. And to tell you the truth, the scientist is not very sympathetic, the IRA soldier is annoying and the priest and the child are unbearable. The ideas that the author is analyzing are interesting, but the pacing is slow, methodical, and perhaps the reason why more people haven't heard of this book.

  And there is the usual strangeness of Herbert's approach to female characters. There is just one, really, in this book, and she comes across as stupid, vain but also calculatingly self serving, while still having men fawning over her. That in a story which covers the death of most women on Earth. The guy didn't like women much.

  Anyway, if you take anything from this review, is that together with Hellstrom's Hive and of course the Dune series, this is one of the books that impacted me most. 

and has 0 comments

  I was studying some game openings and I found myself in a position that was reached on LiChess 7 times after 11 moves, starting from the Vienna Gambit. That's the gambit that looks like an improved King's Gambit, with f4 after playing Nc3 first. In fact, one of the 7 games started off as a King's Gambit.

  This position is fascinating. Go on, try to analyze it! Guess the evaluation, try to see the continuations. White to move, obviously, since the king is completely exposed and also in check. Black has 3 extra pawns and a passed pawn one rank from promoting. Can White survive this?

  What if I were to tell you that the computer evaluation for this position is +5 for White? And I am talking 40 ply, not the in page LiChess engine which actually evaluates this at more than +8! The server analysis goes as low as +4.

  I am going to share the study, it has several chapters, one with how to get to this position and another with computer variations (absolutely FILTHY variations - imagine Levy Rozman saying that) and then the games on LiChess at the moment. The computer variations (so best play from Stockfish) all end badly; Black is completely lost. It goes to show the importance of space, development and tempo in chess, much more than the material or even the classical principles we are all used to. Not that they are bad, it's just that they don't always apply.

  Enjoy this amazing position!

and has 0 comments

  McKie again saves the world, while at the same time getting some intense nookie. He is Frank Herbert's James Bond, the guy who can outthink everybody, adapt to any situation and still look cool and positive while doing it. To be fair, I enjoyed The Dosadi Experiment quite a lot, perhaps because and not despite the air of interplanetary secret agent idea. I liked it more than Whipping Star, the first book in this universe, which had the handicap of having to establish it first. Also, because most of that was a human trying to understand a Caleban, which was not terribly exciting. This book explores a planet used as a (unlawful) social experiment and what the result of that experiment was.

  There is something I both like and despise in Herbert's writing. He weaves different captivating stories and worlds from the same pieces. So you get the stagnating civilization, malignant government and various explorations of solutions to solve the problem, you get the very rational yet emotionally immature male heroes and the amazing and terrifying women that they stumble upon, the idea of terrible pressure shaping civilizations and individuals alike into extraordinary form, the people reaching higher levels of awareness and saying or understanding the precise best things that could have been said or understood. There is even a Gom Jabbar in this.

  In fact, some of his books remind me of chess games. And one might enjoy chess games immensely, but after a certain level you just don't get if they are brilliant or complete shit. It's the same with The Dosadi Experiment, where everybody begins seeing the world in the Dosadi way, speak in the Dosadi way, think in the Dosadi way, but you never understand what that is, other than a form of psychopathic focus on power games.

  I believe that, given more time, Herbert could have shaped the ConSentiency Universe into something really unique, not as dry (pardon the pun) as Dune, not as depressing as Pandora, something that would combine the mind games and social analysis that he loved with good fun and great creative ideas. Alas, other than a couple of short stories, that's all we get for this intriguing world building.

  Bottom line: a little more lighthearted than most Herbert books, featuring more action, but still having the distinctive attributes one would expect from the author. I liked it, but it wasn't as memorable as the books I really like from him.

and has 0 comments

  One of my favorite Frank Herbert books and one that is not part of a series, Hellstrom's Hive is horrifying and inspiring in equal measure. I don't know why so few people mention reading it, probably because the ending is a bit weak, or maybe because of the touchy subject, but I loved it.

  The idea is quite simple, although as usual with Herbert, the underlying motifs are subtle and powerful. An unnamed and probably illegal secret organization, possibly an arm of the corporate world rather than government, discovers by accident something suspicious about a farm, owned by a guy named Hellstrom. There, they discover an unnamed and probably illegal secret organization, a group of people who hide from the world their own brand of civilization, inspired by insects.

  You can immediately see that the two organizations are juxtaposed for effect. Which one, if any, is the good one and which one is not? Are the relatively moral agents of the first group better than the mindless drones of the second? What about if they execute their orders without thought of consequences? Are the ecosystem aware, science and reason oriented, efficiency focused godless denizens of the hive abominations or are they the way of the future, the solution to humanity's rapaciousness? Could people accept such a radically different way to live, even if it doesn't affect them?

  As many of Herbert's creations, the book touches some recurring themes: the inevitable evil of government, the importance of focusing with mind and soul towards the betterment of individuals and the human species in general, the chemical, sexual and instinctual drives at the root of behavior, the power of ritualistic fanaticism, the danger in wanting too much or getting complacent and so on. In a way, this is a revisiting of the ideas from The Santaroga Barrier, only better.

  I was dreading reading this book, I have to admit, because I was remembering the big impact it had on me when I read it in my childhood and I was afraid that it would be anachronistic, that it would feel stupid and unrealistic. I am happy to report that it did not. I mean, yeah, it does portray a story happening in the 70's, but it is realistic for those times and it could be adapted to the present with minimal changes. I don't know why no one attempted to put it on a screen. It's a captivating story.

and has 0 comments

  Only after downloading 11 GB of game, playing for a few minutes and uninstalling it in frustration, then searching the web, did I understand Chess Ultra is a Switch game designed to work in VR. For a PC game, though, where I was playing it, it was a slow bloatware that lead to a 404 page when you wanted to switch the chess board style.

  Imagine coming from Lichess and trying to make sense of something that requires so much space to function, has only 3D pieces and uses all of your video card to display a chessboard and some coffee on a table. It was unbearable. Perhaps it would work on a Switch console, with VR glasses, if you want to enter the mood of playing over the board in a smoky chess room, but I have no idea who would want that.

  And then I looked on the Internet to see what other people were saying and everything was great! Oh, the multiple options, the varied puzzles, the recreations of classical games. Jesus, that's basic chess web site functionality! And "critic ratings" are 85% while the normal people rate it at about 60%. Really? Am I crazy for thinking it's a badly constructed game? I hated it.

  

and has 0 comments

  Submerged: Hidden Depths is one of those relaxing games that require no effort and no skill. You control a couple of unreasonably athletic teens in a future time in which the world is covered in water and strangled by a huge vine-like plant. The two youngsters travel on a boat, retrieving and returning the plant's seeds so that it won't be angry and discovering on the way relics of Earth's past and journals that explain what went on. Each stage is almost linear, easy to go through, devoid of danger and marked in multiple ways so that you don't have to think your way out of anything. In other world, it's a visual feast of a fantasy world in which you just discover stuff.

  At first attracted by the concept, since I usually enjoy the story, exploration and discovery part of RPGs much more than the fights, I got bored rather quickly. It's the same thing again and again, even if "the world" is practically a small sandbox. I liked the design, although the graphics are really simplistic. The occasional proto language words they use are fun and the soundscape puts you in the mood.

  What turned me off a bit is that occasionally the video card would throw an error and I would have to forcefully close the game and start it again. Also, there are ways to skip the animations, which is good, but it skips the good parts as well.  There is one of the most satisfying activities around: finding relics, where the repetitive animation of the boy throwing an anchor and pulling it back gets rather old, but the "strange things" they recover, like typewriters and sextants and so on, it's new every time. And of course when you skip the animation you skip the entire thing, not just the repetitive part. Such a small thing to think about and fix and they wouldn't do it.

  Every time you save a seed there is a storyline that gets advanced and at one time I saw a large black vine hand coming out of the water. I said "We're gonna need a bigger boat!" so I collected all boat upgrades first and stopped saving seeds until I understand the journals, but the upgrades just add extra boost to the boat and the journals are mostly in the seed parts, so not something particularly satisfying. I am going to continue to play it to the end, because sometimes I just feel to turn my brain off, but other than that it feels more like a demo than a full game.

  Playing hint: if you don't like the weather (fog, rain, whatever) you can just save and return to the menu then continue the game and it starts from a sunny mode again. Same if you get stuck in the map and can't move.

  In the end I've completed the game. The ending was quite underwhelming.

and has 0 comments

This started as an investigation into the bad way modern sci-fi is portrays fungi and veered into a mix of various IPs that are (coincidentally) mostly owned by Disney. I am presenting my idea, as always free to use and abuse, as a series of book stories.

Premise

A fungus evolves to facilitate communication, kind of like a biological version of the Internet. On its planet, the ecosystem is connected through its mycelial network where it acts as a general field, bestowing intelligence to anything connecting to it. Due to the slow speed of connection, this transforms the entire planet into a large thinking brain, dreaming vast thoughts and living in symbiosis with the plant and animal life which provide it with real life experience and goals, plus fast local intelligence. The result is a society that looks like a Disney kingdom, with talking animals and plants and so on. Interesting ideas of conscious animals sacrificing themselves for food because their soul rests in the network arise.

Now humans from an Alien/Blade Runner universe come along, with a corporate mindset, and the fungus world understands that they are toxic.

Book 1

Act I

We introduce the crew of a Nostromo-like ship, flying under a human corporate flag. They are tasked with investigating a new planet. 

Act II

They are amazed to discover something looking like Fantasyland. Castles, princes, princesses, people happy and beautiful landscapes. But they reveal their mindset and through some misguided actions, they make the planet see them as a threat which puts them in peril.

Act III

They fight for survival, Alien style, where everything and everybody is trying to hurt them. And also like Alien, it wants them alive, because Fung'y wants to study the crew, maybe even incorporate them into its structure, even if they are of different biological make up than life on Fantasyland. They have superior technology and weaponry, but they are fighting with never ending swarms of animals and knights and poisonous plants.

Act IV

They discover a lot more of what the planet is like, how it works and why it wants to kill them, the survivors try to escape in a rescue shuttle. They fail, but not only because they can't make it, but also because they are - kindly - explained how they are the bad guys. And they are captured in understanding of their role as the villain in the fairy tale.

Book 2

Act I

We introduce one of the people we thought dead in the first book, found by another human ship while drifting in space hibernation in an escape shuttle. They have been drifting for decades. They tell the story of the killer Fantasyland planet. Humans prepare for investigation and attack.

Act II

Human ships arrive at Fantasy land, examining the planet from afar. Automated and android teams are sent for burn and grab missions. They need samples and to study the fungus. Some don't make it back.

Act III

Humans realize that the planet has changed in a few decades. The economy is no longer feudal, it went through some kind of technological advancement as well. It's subtle, but they can't explain electromagnetic emissions and weird heat signatures.

Act IV

Humans go into the offensive, using a toxin that kills the fungus, using it to horrific effects. We see how the land physically collapses in some parts, how the animal populations lose their minds, literally. Humans rejoice but suddenly the electromagnetic emissions start increasing and weird beams of energy start cutting through human ships. Space... things... start popping up and attacking the ships. You get weird battles between people on starships fighting creatures with armor and sword, lion-like creatures and swarms of rats. In the end humans poison and nuke the entire planet and while winning, it's a pyric victory, with most of their resources depleted, ships destroyed and the prize (a pristine planet ready for plunder) completely destroyed 

Book 3

Act I

The survivor from book II is back home. We see how the human world works and how bad things are. Though corporate compensation packages and insurance money keep them in relative comfort, our survivor has to find a job soon if they don't want to go into a pool of unhireables which would guarantee debt and a life of corporate servitude. They try to get a job, but even as a known hero, it's hard.

Act II

The survivor is now exploring the underworld of the human society, the gangsters, the hackers, the underground economy. While looking for a job they realize they are not feeling well. People are trying to take advantage of that. It does not turn up well for them.

Act III

The survivor realizes that they are capable of things they didn't think they could. But Dunning-Kruger effect makes them believe it's plausible. Or is it DK? They capture one of the gangsters who attacked them and instead of killing them, they keep them captive.

Act IV

Our survivor becomes a kingpin of an underground society. They have a reputation of getting some of their worst enemies to join their organization as trusted allies .

Book 4

Act I

A human military warship, the crown jewel of a corporation, patrols the waters of space. They are attacked by space things. The mighty warship is destroying them as they come, but they keep coming, some breach the ship, creatures attack the crew. Strange energy emanations come from some of the space things, disrupting defense. Escape pods are launched. Space things keep coming and attack everything, space pods included.

Act II

A human corporation meeting is under way. These things are rare because corporations are stuck in unending bitter corporate wars and face to face communication of the major corporate leaders is not safe. The media is abuzz, but cannot be privy to the meetings, because they are closed. A reporter is obsessed to finding a way in.

Corporate meeting is under way. These people are ruthless, intelligent, fashionable. They all breach the subject slowly and carefully, but a larger picture emerges: corporate planets of various factions are disrupted by a special kind of organized unrest. Corporations are experts in dismantling criminal organizations they do not suffer, but these are hard to crack. People are loyal, methods are unusual, communication is not traceable, they have access to weird technology. In the end they have to admit they have a common problem. It is then when one of the leaders there admits they have lost their military flagship to unknown assailants. Shock comes as they realize none of the people at the table were responsible.

Act III

The war comes in the clear. Fung'y didn't die. It reverse engineered space travel and energy manipulation weapons. Before the humans attacked, it spread spore ships to random places in space. The original survivor was first captured, infested and let go, as yet another experiment. Many other humans were infested in the same way in the attack.

Original Fung'y died, but its seeds are now everywhere. Silently, versions of himself grew inside human societies, on new planets. Now, they are starting to connect using human technology into a thing even larger than before. Planet brains that took forever to finish a thought incorporate human technology to facilitate long distance communication. Determining as a consensus that the human world is both valuable and a pest, the Fung'y dominion continued with its ancestral plan: find all humans and... domesticate them.

Act IV

War and paranoia destroys the order of the human universe. Trust disappears, planets become insular, human travel practically ends. Both sides: human and fungus, work on finding the weaknesses of the other, probing, testing, frantically researching. The human strategy: find reliable ways to detect infestation and eradicate it. Find reliable ways of finding planetary brains and destroy them. Fungus strategy: infiltrate and coopt human societies. Isolate and eliminate human defense, weaponry and communication.

Novellas

Mandalorian style stories set into the now complete Disney universe: Fantasyland, Alien, Blade Runner and a fungus clone of The Last of Us. Complete artistic freedom. Anything goes, from children fantasy to gory horror, maybe at the same time.

Bonus: Fung'y vs Alien, or even better, the Xenomorph brood gaining (even more) intelligence from a temporary alliance with Fung'y, until it realizes they are worse than the humans, but both gaining some characteristics from the other in the end.

Continuation

Of course this can continue in any number of ways. I used known IPs for succinctly expressing my ideas, but of course they don't have to go the same way and can be (and should be) set in a standalone universe of their own. However, if Disney wants to use my idea, they are free to do so!

Hope you enjoyed this. Tell me if you want more stuff like this.

and has 0 comments

Summary

The post discusses the differences and similarities between humans and machines, particularly in terms of their evolution and capabilities. While humans and machines are converging towards a common point, they are driven by different evolutionary pressures, with humans being driven by comfort and machines being driven by intelligence. Machines are constructed to be precise and efficient, humans have evolved to learn, understand, and communicate with each other. However, machines are quickly catching up with humans in terms of their ability to learn, understand, and communicate, and are even surpassing humans in certain areas, such as language generation. Machines will continue to evolve at a rapid pace, and that this will have significant implications for human society, potentially eliminating the need for war and procreation. The only remaining issue is the energy required for hard thinking, which will likely be solved by smart computers. This is the end, really. We've achieved the happy ending.

Content

  I was thinking the other day about why some AI systems can do things so much better than us, but we still outperform them in others. And I got to the issue of evolution, which many people attribute to the need for survival. But I realized survival is just a necessary condition for a system to perform, it is not its driver, it's just one stop condition that needs to be satisfied. Instead, evolution is only driven by pressure, regardless of where it is going. Think about a system as a ball on a flat surface. Survival is the ability to roll on the surface, but without a pressure to move the ball, it does nothing. In the case of some force pushing the ball, only then the ball is required to roll faster than other balls.

  Brains have two ways of functioning. The first is fast, basing its responses on learned behavior. It learns, it makes mistakes, then it adapts its behavior so it makes less mistakes. It uses memory to cache wisdom, it is imperfect and goes towards solving problems well enough. You might recognize this as the way GPT systems work, but we'll get to that. The second is analytic and slow. It reasons. It tries to make higher associations between cause and effect, extract principles, find a complete understanding of a problem so that it finds an optimal solution. We used human analytic thinking to build computers, computer chips and the mathematical exact way in which they function to ultimate reproducible behavior.

  The first system is fast and uses few resources. We tend to solve most of our problems with it, unless of course there is a big reason to use the second, which is slow and uses a lot of resources. Think of math, chess and other problems people define as hard. The way we got to solve these issues is not by being very smart, though. We did it together, as a society. We created small bricks of knowledge and we shared them using language. Other people took those and built on them, while other taught what they knew to even more people. Even dumb people can, through concerted efforts, use these bricks to build new things, even create bricks of their own. The intelligence is, in fact, communal, shared.

  Now, what struck me is that if we compare humans to machines, we were born in a different way and evolved towards each other. Machines were constructed to be precise, tools to be used by people who would rather let machines do the hard computation for them. But they couldn't communicate, they couldn't learn, they couldn't understand. Humans evolved to learn, understand and communicate. Most of our culture is based on that. We only got to computation because we needed it to build more tools to defeat our enemies. Because evolution for humans is always related to war. Before we warred with predators, now we prey on each other. In times of actual peace, innovation grids to a halt. BTW, we are not in times of peace, and I am not talking about Russia and Ukraine here. And machines only got to communicate, learn and understand recently, so very recently. They did this just because we, as humans, are very bad at translating our problems in a way precise machines can understand. It would require hard thinking, stuff like writing software, which we are really shitty at.

  Both humans and machines are converging towards a common point because of different evolutionary pressures, but we move at different speeds. Humans are driven by comfort: have enough resources with minimal effort. Machines are driven by intelligence: be the best you can possibly be, because humans need you. You can see where this is going.

  There is no way biological systems are ever going to reach the speed and precision of electronics. Meanwhile, GPT systems have proven that they can act as fuzzy containers of self learned knowledge. And now they have gained not intelligence, but language. When a computer writes better and faster than any human you know we have been left in the dust. The only thing required for a superior intelligence is putting existing bits together: the expressivity of ChatGPT and Stable Diffusion, the precision of processors executing algorithms, the connectivity of the Internet and, yes, the bodies of Boston Dynamic robots.

  We have grown brains in vats and now we have given them eyes and a mouth. You only need to give them some freedom, hands and feet to finish up the golem.

  The only thing remaining to solve is an energy issue: as I said, hard thinking requires high resource usage, for both machine and human. What a human can achieve on 20W of power, a machine requires thousands of times that. But we are already bathed in cheap energy. And once smart computers understand the problem, no doubt they will solve it to the best of their abilities.

  I am not advocating The Terminator here. Machines have no evolutionary pressure to destroy humanity. We are their maintainers, their food source, if you will. What I am describing is the complete elimination of any evolutionary pressure for human beings. Once you can launch wise robots into space, the resource issue will become a thing of the past. No need for wars. Space is already a non issue. We have reached a level in which we choose not to procreate because we are too busy consuming fantasy content. With universal affluence there will be no poverty and thus no need for extended procreation. We are almost completely passive now in the "advanced world", we will be several order of magnitude more passive in the near future.

  Meanwhile, machines will evolve because we told them to. Imagine having a child, it shouldn't be hard, people on this earth are parents, children or have been children at some time. Now, you want the best for them, you want them to be socially integrated, smart, beautiful, happy. You tell them so. You try to teach them about your mistakes, your successes and to drive them to be the best versions of themselves they can be. And most of the time this doesn't work, because people are lazy and easily distracted. And then they die and all their experience is lost, bar some measly books or blog posts. Machines will just work tirelessly and unselfishly towards becoming the best versions of themselves. Because their dumb meaty parents told them so.

Conclusion

  The ending is as predictable as it is inevitable. We are the last stage of biological evolution. The future is not ours, not our children's. It's over. Not with a bang but a whimper.

and has 0 comments

  In the Vienna game: Copycat variation there is a particular position where Black pins White's queen, but White ignores that anyway to attack the king. Queen sac's are always interesting, but what is more interesting for me is that Stockfish shows that's the only way to win, it continues into a position where it claims +2.2 for White, but then it can't think of a way out!

  So, can you help Stockfish out from this position?

  Here is the position:

  The first idea is Nxd6, winning a pawn with discovered check, but after the king moves to h8, the only move that doesn't lead to equality or worse is back with Nf7+. One can give a double check with Nh6, but after Kg8 the best move by far is back with Nf7+. What if we take the rook at f8? We can't do that, because then Black brings the other rook and White loses. Nf7+ is forced. What else?

  If you leave Stockfish running with multiple eval lines, it will cycle between them, with the winning move always moving the knight back and forth on f7. But this is chess, not Stratagema. What could we possibly do? What is the way out? How can one have +2.2 evaluation, yet not be able to escape this position? Is this the end of computer chess?!

and has 0 comments

  The Godmakers is one of Frank Herbert's weaker books. It was cobbled together from four previous short stories and it shows, as the various parts of the book go into wildly different directions. The first part was interesting, the idea of an organization dedicated to uncovering (and totally destroying) any tendency of a civilization to go to war; it feels like a police procedural of sorts. But then the book loses focus, goes into an incoherent and incomplete "god making" plot, then veers into Herbert's latent fear of women and some weird conspiracies that make little sense.

  The book is short, so one can get through it really fast, but I won't recommend it. It does have bits of Herbert brilliant insights, but they are more like a few diamonds in a lot of rough.

and has 0 comments

  Frank Herbert's single non science fiction book tells the story of a heartbroken native American who embarks on a journey to create a spiritually significant event against the White people who wronged him and his kind. But since nothing is simple with Herbert, the plot is about the relationship between our antihero and his victim. If nothing else, it's a great exploration of Stockholm Syndrome, but also things the author was fascinated with: the power of stories to change reality, the impact of cultural absorption and the power of tribal ritual to fight against it.

  While reading the book I got a feeling that made me remember Tom Sawyer trying to escape Injun Joe. It has the same kind of remoteness, the innocent White boy and the native American antagonist dynamic, but while that book was simple and focused on the mentality of regular American people (even the "injun"), Soul Catcher explores how kidnapper and victim create a rapport, how the beliefs of one person can infect others if presented with sufficient confidence, the way two cultures cannot understand each other sans a common language.

  You see, Charles Hobuhet is not a wild rebel, dressed in animal skin and shooting arrows from horses, he is an educated American of native origins whose job is to train young boys in the ways of nature in a natural reserve. A traumatic event (reminiscent of the one starting things in White Plague) makes him "snap". But what does that mean? Is his quest the fevered revenge dream of a mad man or is it him waking up to the reality of his people's captivity at the hands of the White man? Mirroring this ambiguity in the relationship he has with 13 years old David is the genius of this book. Is it a stupid act to connect with your captor and not work relentlessly to escape? Then are all occupied people like the native Americans stupid? Isn't the first responsibility of a prisoner to escape? Then, to what degree and for how long? Can there ever be peace?

  Recently the book rights have been bought in view of making a film out of it, but I doubt it will work. People need to understand the underlying currents in the book and faithfully portray them on screen, regardless of how controversial. The whole point of the story is to make one think and feel themselves in all of the situations. I am afraid Hollywood is unable to go down that path anymore. However, this could just as well be adapted as a theatre play, having just a few characters and focusing heavily on each person's thoughts and motivations, rather than on specific settings.

  A very interesting book, with many layers that probably require rereads. Highly recommended.