and has 0 comments

The Nazi officer smirks, as the prisoner begs for his life. Instead of any human feelings, he just revels in the pain he inflicts. He is powerful, merciless, and stupid enough to be foiled by the heroes who, against their better interest, came to liberate the helpless victims of this evil butcher. Change the channel! The heartless businessman pushes for more sales of the opioid drug his company produces, destroying the lives of honest, hard working Americans living in flyover country. Change it again! The evil general commands the destruction of a helpless village, laughing maniacally while the future hero of the story vows revenge in Japanese.

You've heard it before, you've seen it before and you've read it before. The mindless, unreasonably evil character who has two purposes only: to be totally unlikeable, an example of what not to be, and to be defeated by the hero, an example of what you should be. But it's not enough! The hero must be a "normal" person, someone you can relate with: powerless, bound by social contracts, connected with people in their community, wanting nothing more than to live their life in peace. But no! This evil asshole is just determined to stand in the way for absolutely no other reason than gaining ultimate power, more than they, or anyone else, deserve. And the hero needs to overcome impossible odds just to have the opportunity to defeat, in an honorable way, the villain. In the end, they will prevail thanks to a combination of friendly help, evolving to a higher level of power (which was always inside them) and sheer dumb luck.

Now, the Dunning Kruger folk will just lap this story up, imagining themselves the hero, but realistic people will just think "wait a minute! If this guy who is well connected in his community, strong as an ox and looking like The Rock, after focused training that he immediately picks up finding magical and physical powers that are beyond reason, has almost no chance of defeating the villain and only gets there through luck, then what the hell chance does a normal human being have?". And a few broken people would ask themselves if the villain wasn't a bit right, wanting to destroy this pathetic place we called "the world".

Where did these stories come from? Why are we suffocated by them and still consuming them like addicts? What is the result of all that?

The psychopathic villain trope is just a version of the old fashioned fairy tale: the knight and the dragon, the peasant and the lord, the girl and the lecherous wizard, the light and the dark. It is the way we explain to little children, who have no frame of reference, that there are ways we prefer them to be and others than we do not. It's a condescending format, design to teach simple concept to little idiots, because they don't know better. Further on, as the child grows up, they should learn that there are nuances, that no one is truly evil or good, that all of us believe we are the protagonist, but we are just a part of a larger network of people. This we call "real life" and the black and white comic book story we call "fantasy", designed to alleviate our anguish.

Yet we stick to the fantasy, and we avoid reality. And it's easy! In fact, it's much easier than any other strategy: close your mind, split your understanding into just two parts, one where you feel comfortable and the other which must be destroyed in the name of all that is holy. To even consider the point of view of the other side if blasphemy and treason. In fact, there is no other side. There is your side and then there is evil, darkness, void, unknown. Which conveniently makes you the good guy who doesn't need to know anything about the other side.

OK, maybe you can't win every battle. Maybe you will never win any battle. But you are a warrior at heart! You don't actually have to do anything. And as you wait for the inevitable defeat of evil at your righteous hand, you can watch other heroes like yourself defeat evil, stupid, one sided villains. And it feels good. And it has been feeling good for as long as stories existed, then books, then plays, then movies and now video games. Yet never have we been bombarded, from every conceivable angle, with so many versions of the same thing.

If hero escapism was a pill that made life more bearable, now it's most of our lives: films, series, games, news. We were raised on them and we are being tamed by them every single day. They are so ubiquitous that if they are gone, we miss them. It's an addiction as toxic as any other. We can't live without it and we pay as much as necessary to get our hit. And this has been happening for at least two generations.

So when we are complaining that today's dumb entitled teenage fuck generation is incapable of understanding nuance, of moderation, of rational thought, of controlling their emotions, of paying attention for more than five minutes to anything, of dialogue, of empathy... it's not their fault. We raised them like this. We educated them in the belief that they are owed things without any effort, that their feelings are valid and good and that it's OK to consider everybody else evil as long as they are different enough. That we must be inclusive with any culture, as long as it is also inclusive, otherwise exclude the shit out of it.

The trope of the psychopathic villain did not teach these people to be heroes, it taught them to be the foil to the people too different from them. And here we are. Psychopaths on all sides, thinking they are good and righteous and that sooner or later ultimate power will be theirs. The only positive thing in all this: they believe the power is inside them and will reveal itself when most needed, without any effort or training. That's what makes them dumb psychotic evil villains, completely unreasonable and easy to defeat.

If only there were any smart heroes left.

and has 14 comments

  Today I saw a Windows Update message that I can install Windows 11 on my computer. Great! I let it install and all went without a hitch. I don't see any problems with it, my software works fine, the only problem is that the taskbar icons are in the middle of the screen rather than to the left and it has that default setting of huge annoying icons instead of text, grouping all windows of the same type and so on. Simple, just go to settings, right?

  Wrong! Windows 11 now comes with a taskbar with LESS options than before. If you continue using it you will have to live with grouped apps under huge icons, with no recourse whatsoever!

  Luckily, Michael Crider from PcWorld to the rescue. Just download the setup to Explorer Patcher from GitHub and run it. The Windows 10 taskbar will be back. Just right click on it and select Properties and you can customize it even better than the old one! Cheers, Michael!

and has 0 comments

  Can we use the scientific method as a guide for life? Let's find out!

  In these times science is either misunderstood or maligned (more often both), but what do you think science actually is? The "simple" Wikipedia definition is "a systematic enterprise that builds and organizes knowledge in the form of testable explanations and predictions about the universe", which is a criminally roundabout way of saying it's the result of the scientific method, the one that you see in the picture there. No matter how little you know or how stupid you think you are, the scientific method is a way of acquiring knowledge and then building upon that knowledge. It has nothing to do with nomenclatures, hard mathematics, quantum mechanics or complex lab equipment. Those are results of science, not components. One may build upon them, but might as well decide they want to go another direction.

  Why am I writing this? Because I am not a scientist, but I feel inspired by the scientific method. It provides a sure algorithmic way of improving... well, anything! All you have to do is repeatedly follow four simple steps:

  • Observe
  • Predict
  • Test
  • Analyze

 And while discussing this with anyone is something I enjoy, this post is not about the entire process, but just about the first step: Observation. I strongly believe that what is missing most from our collective lives is observing the world around us. I was reading something about a plant today and I realize that I have no idea what the plants I see are called, what they are useful for, and furthermore I rarely pay any attention to them in the rare cases I do go out and find some. My wife is different. Her life is based on observation and, while I don't always agree with her conclusions, I begrudgingly have you admit that I mostly analyze her observations rather than make my own.

Imagine you are in a biology class in school, let's say primary school and they have to learn botany. Are you seeing it, in your mind's eye? Where are the students? How does the teacher enter the class? What does he do? What do the pupils do then? What tools are they using?

Now tell me, where did you imagine this class taking place? Because when I did it, I imagined a room at the first floor inside a concrete building. The teacher enters the room and writes something on the blackboard and the children open some textbook. Perhaps it's a whiteboard and children have tablets, because it's the future and I am fucking old. But where are the plants under study? If we are lucky, there are some in the window behind the teacher's desk, because they have a small, but higher chance of surviving there than anywhere else in the classroom. If the school has a high enough budget one can imagine an occasional field trip with the kids, using a bus to go to a botanic garden and walk around for a bit. An artificial and abstract representation of something that is never observed.

How can one study anything without observing it? In an average class what pupils are observing are the opinions of other people, translated into text and pictures in books. They move from subject to subject, always basing their learning on what someone else saw and abstracted away. They are taught, in a consistent and constant way, to base their thinking on what people in authority have chewed and regurgitated for them. It doesn't matter if those people are right or wrong, that's not the argument I am making, it's about what we are actually learning, in schools and then later in everything we do. It only takes one moment of disconnect, of betrayal of trust, for the foundation of entire lives to be shattered, because if you suddenly learn you may not get the right information from the people you thought of as experts and authority figures, then your entire life experience so far may be a lie.

Most people dislike and distrust science because it is presented in an abstract manner, removed from day to day experience. But that's not science! Science is based on *your* experience. The very word means knowledge. And while you are bombarded with information every minute of every day, that's not knowledge unless it fits in your chain of experiences.

Now tell me another thing: what do you want to improve? Your life, probably. How do you define it, what are its components, how do you measure its quality? In the end (or is it the start), how well are you observing your life? How do you observe yourself, the people around you, the world in which you live?

Let's start there, with defining ourselves and our place in the world, let's observe the immediate reality of our existence. We'll wing it from there. It won't be science until we make testable predictions, actually test them and then adapt to what the analysis tells us, but it's a start. The alternative is to try to fix something without understanding how it works. Or worse, waiting for someone else to do it for us and hoping they understand it better than we. We will end up hitting something repeatedly, expecting it to start working as we want.

I was reading an article a few days suggesting that he have evolved to hold opinions that make us "win" not that are necessarily true, that those opinions are there to define our belonging to a social group and not to inform our actions according to reality. The scientific method appears to do away with emotions and instinct, thus feel unnatural, but in the things we choose observe we find ourselves, in the predictions we make we put our hopes and in the effort to test and improve our understanding we enforce our will.

Do you feel lacking control over things? Are you angry and frustrated? You might not have much power, but *this* you can do no matter who you are, where you are and who stands with or against you. Science: see, think, try, choose.

and has 0 comments

I got this exception at my work today, a System.ArgumentException with the message "Argument passed in is not serializable.", that I could not quite understand. Where does it come from, since the .NET source repository does not contain the string? How can I fix it?

The stack trace ended up at System.Collection.ListDictionaryInternal.set_Item(Object key, Object value) in a method where, indeed, I was setting a value in a dictionary. But this is not how dictionaries behave! The dictionary in question was the Exception.Data property. It makes sense, because Exception objects are supposed to be serializable, and I was adding a value of type HttpMethod which, even if extremely simple and almost always used as an Enum, it is actually a class of its own which is not serializable!

So, there you have it, always make sure you add serializable objects in an exception's Data dictionary.

But why is this happening? The implementation of the Data property looks like this:

public virtual IDictionary Data { 
  [System.Security.SecuritySafeCritical]
  get {
    if (_data == null)
      if (IsImmutableAgileException(this))
        _data = new EmptyReadOnlyDictionaryInternal();
      else
        _data = new ListDictionaryInternal();
    return _data;
  }
}

Now, EmptyReadOnlyDictionaryInternal is just a dictionary you can't add to. The interesting class is ListDictionaryInternal. Besides being an actual linked list implementation (who does that in anything but C++ classrooms?) it contains this code:

#if FEATURE_SERIALIZATION
  if (!key.GetType().IsSerializable)                 
    throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "key");                    
  if( (value != null) && (!value.GetType().IsSerializable ) )
    throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "value");                    
#endif

So both key and value of the Data dictionary property in an Exception instance need to be serializable.

But why didn't I find the string in the source reference? While the Microsoft reference website doesn't seem to support simple string search, it seems Google does NOT index the code GitHub pages either. You have to:

  • manually go to GitHub and search
  • get no results
  • notice that the "Code" section of the results has a question mark instead of a number next to it
  • click on it
  • then it asks you to log in
  • and only then you get results!

So bonus thing: if you are searching for some string in the .NET source code, first of all use the GitHub repo, then make sure you log in when you search.

and has 2 comments

Intro

Four years ago I was writing about being on social media for a year, as a follow up for another post about being on social media for four months. I do promise not to make this into a series. Probably it will be the last post on the subject anyway. Hopefully.

So five years ago I was saying: "I had high hopes that once I connect with all my friends I would share of their interesting experiences and projects, we would communicate and collaborate better, we would organize more parties or gettogethers, meet up more frequently if we are in the same area. Be interesting, passionate; you know... social. Instead I got cute animal videos, big pointless images with texts plastered all over them". That has not changed at all. My hopes waned, but never completely vanished, as I was trying and tweaking various methods of controlling content, but the quality of things has never actually improved. My desire to share in the actual life important events of others is still there, only it's clear I won't get that from social media. Long story short, I intend to stop reading social media, instead trying to find an effective method of getting the connection I need.

Facebook

I have to admit I've had some success in "taming" the platform to provide some interesting content. I've unfollowed every source that didn't give me relevant information, I've followed science, technology and medicine accounts, I've actively used the "Hide posts like this" option until my "wall" became less annoying. I even tried "Liking" stuff that I wanted more of, although that actually seemed to be the least consequential action I was making (maybe because of the algorithm's superficial understanding of what I am actually looking for). However, it was always a tiring activity, having to aggressively fight the system instead of being served by it. Like riding a raging bull to work every day. Inevitably, some click bait or ad post would arouse my curiosity and, after clicking on it, I would be presented with more of that crap, even if I didn't like it. Meanwhile, my "friends" were posting photos of themselves, political rants and useful announcements like when they had their latest baby. I mean, even programmers that I know are active were never posting anything remotely technical or at least news worthy. That, frankly, I don't understand.

At the same time I tried as best I could to post science and software links and relevant content about interesting books and whatever caught my fancy that was NOT funny animals or sarcastic humor (although some of that might have slipped in) in the hope of improving the walls of all my friends. Some seemed to like it. I guess some of you are my *real* Facebook friends and most of you are not! 

But the app itself figured out I was less engaged (or just spammed everybody because why not) and started showing me alerts for absolutely everything. People are live streaming, people are going to events, people are having a shit. And with the new normal for everything to be fighting for your attention, it got annoying. I had to navigate the large (and increasing) number of possible alerts and choose what I wanted because the default is that you want everything all the time to snap you from whatever you are doing. Like that makes sense.

Twitter

There are some things that I want to document, but I don't want to blog about anymore. They are not appropriate on Facebook either, as I believe the audience is wrong. One such example is TV (if one can still call them that) series, where I can throw a small rant, complete with hashtags, for everyone who would be interested in opinions about the show, not my own personal stuff. I guess it might work on Facebook, but I haven't tried. The hashtaggy thing should remain on Twitter, it feels only right. Also, it has this system where you are not friends with anybody, you just follow what they are saying. That's good.

Like with Facebook, I've curated the sources of my tweets and the content is mostly... really really informative. I want to say that I will devote no more time reading Twitter, but it's a lot harder to do than with Facebook. Twitter has a very simple, but somewhat effective filtering system based on keywords. Once I removed political keywords, US president names, everything -ist, -phobe, woke and the like, the bullshit I normally have on Facebook largely disappeared. Actually, I haven't done that on Facebook because on Twitter I mostly follow international accounts (in English) and filtering posts on exact words in Romanian, with all of its conjugations and possible forms and lettering would be a nightmare.

BTW, I've set up Twitter to give me tweets in English, Romanian, Dutch, Bulgarian, Italian, German and some other languages. I think the only tweet I got in another language than English was this year, and only because I has followed the guy myself.

There are issues on Twitter as well. One of things that I had to struggle with constantly is telling the app to show me tweets in chronological order. Instead, it wanted to decide FOR ME what I should be looking at. And, when it finally got it straight that I want all my Tweets as they come, they added a feature to restrict the number of tweets that are loaded. The button to "Show more Tweets" looks exactly like any other link and I may just miss it entirely. I can't mark tweets as read, specify a lower time bound for tweets or disable that stupid button. And even if I use the button, I can only do it a few times until it won't load more things because software developers on mobiles never used WPF and then made fun of it for being slow and working only on Windows. (look up Virtualization in WPF, guys!)

And the same issue I had on Facebook I had here: most developers or movie people or science people share all kind of personal opinions and rarely what they are working on, links on the things that inspire them or anything actually connecting anyone with anything. Meanwhile the platform is going further towards blinky images and large texts and video previews and longer text. Having Dorsey step down from Twitter doesn't help either, as corporate assholes will make the decisions now.

Anything else

I have not been active and I don't intend to become on any of the Instagram, YouTube, TikTok, Twitch, etc. platforms, because they are visual in nature. I am more textual.

But I did start to watch more stuff on YouTube and I've got the feeling that many people have started to express themselves more there, as it feels more digestible for younger people. The new "streamer" fad has become very influential. I've found development, science, movie, chess, nature, medicine, humor channels that entertain me an inordinate amount of time while also being very informative. To me watching somebody speak at normal speed about something until they get to the part that actually interests me is torture. Luckily, YouTube has the option to choose a speed of play. It's not exactly a complete solution, but it does help. However watching, let's say, software development videos at 2.5 speed is tiring and you get no inkling on where to skip to get to the good part without missing out.

Of course, having an ad blocker makes this a lot more fun that it would have been without it. I doubt I could stand YouTube otherwise.

But even YouTube has this system in which it tries to control what you are watching, even if it's your Subscription list. If there are too many videos, I feel like it applies a little filtering or ordering. And the list of items in your subscription is generated occasionally, not whenever you open the page.

The video watching stuff will probably continue to take a lot of my time. It's a passive activity, though, so I will have to limit it in some way. More in the conclusion of the post. 

My blog

As you may know, I've moved the blog to my own domain because Google Blogger just decided to automatically, unilaterally and permanently block my blog account. No appeal request was ever answered. I've only had my blog on their platform for 12 years, so who cares? That liberated me, though, to control the full content and functionality of the blog, but it probably lost me a lot of ranking. The result is that very rarely someone comes on the blog for help or interaction. Sites like Stack Overflow solve the issue of finding answers to small problems and people seem to care less about long form content.

Having lately worked in highly paid yet technically dead jobs and a general feeling of "been there, done that" also made me post less and less on the blog. If you look in the last few years, most of the stuff I write about are the books that I read, and lately I haven't been reading that much (except Twitter and Facebook) either. Surely that didn't help people wanting to connect with me. Yet at the same time, I don't want to pretend I have something to teach when myself have not been learning anything new in ages.

If (I am giving myself an out here) I stop wasting so much time parsing walls of stuff trying to occasionally get to something good (BTW, that sounds like gambling, Belgium lawyers! People are performing the same actions but get content they want randomly), watching videos I don't need to watch (because some of them are quite pointless, even if occasionally entertaining) and not watch news anymore (everybody has some agenda behind their news items, but lately it's been so damn obvious that you can't even call it "hidden agenda" and feel smug about yourself), then I should have at least enough time to read more books. I don't know if I will have the material, inspiration and time to research new software technologies in my spare time to start writing meaningful technical content, though. One can only hope. And I mean me.

Conclusion

Lately I've spent my last hour or more before I go to sleep skimming through Twitter and Facebook items, looking for a good reason to continue doing so. I couldn't find it. If I find something interesting (usually on Twitter, but sometimes on Facebook) I share it with my friends on Facebook. It is a rather significant account of my state of mind, since my personal life is hardly something to publish, and these are the things I am interested in.

Before that, I go through my YouTube videos. Some of the things there are what could be considered high level content: documentaries, expert opinions, etc., but most of the ones I find time to consistently watch are short funny animations, short angry rants and short... you get the pattern already.

Therefore my New Year's Resolution (I know they are considered toxic now, but it comes from a good place I think) is to stop reading social media and instead find a more focused solution on getting only exactly the content I need. That requires defining what precisely is the content I need, but at least vaguely I know:

  • I want to find again (if it exists anymore) the software development community that was so active fifteen years ago: blogs, people that share their work and are proud of their accomplishments rather than their opinions on everybody else's, aggregators of actual work, not sharing obvious derivative content or tutorial achievements.
  • I need to restrict myself to the channels where people choose to share educational content. So even if I know someone is a hot shot in software development, I won't just add him as a friend or follow him and hope some day he will stop talking about systemic racism and instead focus on computer systems.
  • Some things will catch my interest for a limited time, like standup comedy for the last year, but I will feel when it starts to get repetitive or slide into something else and cut them off
  • The method of finding relevant content has to be less manual. Instead of trying to find the gem in the mud, just avoid mud in a sea of gems.

Failing at that, I will have to get my content from the original long form content: books. It will be an activity that sounds passive, but it won't be. Books require effort reading them, a focus of attention and so on. More than skimming two page long Internet content, that's for sure. That, if I don't listen to the books instead of reading them, falling asleep and then pretending to have read the thing. No, I won't do that.

I will also continue to share what I find interesting on Facebook. Sharing is caring after all. I just won't read what everybody else is sharing. I know that sounds more self absorbed than useful, but that's the best I can do. The alternative would be to post everything to my blog and repost the links to social media automatically. I just don't feel sharing a link is actually blog post material, which is traditional long form (like this shitty thing no one will read). I mean, how ridiculous it would be to get a link to my blog in Twitter, than you then follow to get to the link I liked while looking at Twitter?

However, it is clear that, as a principle, what I need to remove from my life is as much passivity as possible. I need to involve myself more, pay more attention, focus, make personal connections. That's also something I will attempt to do, though I will likely not share that on social media, except as occasional blog posts on how great my life is and how yours sucks balls.

At this point I only hope you had the attention span to read this to the end, the emotional involvement required for you to care and that you will understand why I don't Like anything you post. I didn't do that even when I was active on social media, I will certainly not do it now.

One possibility is that I will fail at this resolution completely. I gauge this as very remote a possibility, but it exists nonetheless. I really hope someone will smack over the head if I get to that point. I would certainly deserve it. Not you, wife! (she likes smacking me)

I know it's premature, but I wish you a Happy New Year, as I do indeed intend to have one myself.

and has 0 comments

Intro

When learning to code we get to these exercises and tests and katas and interview questions using some array and expecting some magical string or number and you hear they are called algorithms. And they are intellectual, complex, mathematical, abstract, annoying and feel completely random. But when you are actually doing something real, code doesn't look like that at all. It took me years to understand what the problem is and I am going to share that with you today.

The short version is this: If your program logic doesn't look like an algorithm you are probably doing something wrong. Programming katas are simple because they need to be able to check your answers and give an unequivocal result. It's good to know them, but you shouldn't need to know them, because they are not meant for the real world, but for controlled short term experiments. Unless you are going to work for a sorting company, that's a thing.

Now for the long version.

What you expected versus what you get

You get your first job as a developer and your tasks sound like "fix the color of the submit button" and "the report page shows title in the right, move it to the left". And you think "why the hell did I go through those manual Bubble sort algorithms and learned Quicksort partitions if this is what programming looks like?!". The answer is that you will get to a point where your skills will make people feel confident enough to let you design and architect the things you write. Only then the algorithmic thinking will help because you will have decided yourself what the button does and why its color or position are what they are.

When you start designing flows and entire systems and how they click together it helps a lot to see a component as an algorithm: inputs, rules and outputs. "But, Siderite, a button is not either of those!" you will say. And that is true, but also completely irrelevant. Your program logic should not care about a button, but about an input. And now you also see why the summing of distinct array items is a poor substitute for real life problems, because a click on a button is not a value in a properly contained list, but an event. And most programming exercises and even entire computer classes don't treat events as abstract inputs at all.

Lately this has started to change, both in how programming languages look at actions and events as first-class citizens, but also in theoretical and programmatic concepts like observables, streams, functional programming, reactivity, event buses and messaging, microservices, etc. It makes sense to not quite get it when you have not begun to touch these concepts and when everybody and their grandmother focus on the latest frontend framework, rapid application dev tools or extensions to VS Code, but at their very core all of these things are solutions to the same problem, following the same principles.

Breaking reality apart

As you start to climb toward seniority (and that does NOT mean going to Mexico so they call you "señor developer") you learn about Separation of Concerns, as a good strategy to isolate changes, improve readability and testing and ease maintainability and deployment. You learn about writing applications in layers: the UI, the business logic, the database access, etc, which is also about separating concerns. And as you go further and further on that path you realize...

Wait! This business logic thing looks like an algorithm! It abstracts all of its dependencies until all that remains is: inputs, rules, outputs.

But there are things to confound you: events, user input, parallel tasks, race conditions, heavy load use, the cloud. You can use the same tools, though! Abstract everything, separate concerns. What is an event but a signal coming from a source? Your input is the observable source object and the events themselves just values coming in. Or just a method that receives an event object and you handle sending the event someplace else. Everything coming from the user can be handled the same way. Concurrency is solved by maintaining as little internal state as possible and, when absolutely necessary, guarding it against concurrent access via clear established methods, like semaphores and transaction contexts.

Once your logic is clear, your data structured and every external dependency abstracted away, you can run and test every subsystem in isolation. You don't care something is supposed to be a click, or an error, or a network message or on Windows or Linux or how it's deployed or if the database is available and what kind it is, what UI is being used and what it does, where in the world you are and what time it is and so on. Your code is now an algorithm: a set of rules applied on predictable input which can then be tested for an expected output.

A new requirement comes: you change just the part responsible for the requirement. You can write unit tests before or after or test it manually without caring about anything outside that piece of code. A bug is reported: you write a test that reproduces the bug, you change the code, see the test pass and you never had to open a browser or an app or go to some external environment or ask some other team for user access or if you can use the database. How does it sound to be able to code without ever having to manually go through application scenarios?

Of course there will be an ugly user facing piece of code that you will have to write, but it should be minimal. Your logic is sound, almost mathematically provable to be correct, and how you plug it in is irrelevant. Yes, you will have to work with the graphical designer in your team and make it so the nicely colored card slides across the screen, but that is a meaningless process that you play with in complete isolation from your logic. End to end testing is sometimes necessary, but it's a human thing to do, as well. Just check the "feel" of things, how they look, how they move, if it works for you. The only reason why you are going through it is because you have not been able to completely abstract the end user, with their stupid requests and complicated needs and ideas of what beautiful means.

Yet that is beginning to change as well. Artificial Intelligence, of all things, has advanced so far that you can create minimal interfaces using human language requests. "Build me a web page with a list of items that can be scrolled and selected to be displayed in a details pane on the right". I can imagine this can be used in real life only when the logic of the application has already been written and one is able to just plug and play such a monstrosity without much effort, while also being prepared to change the requirements, recreate the entire things in a different way, but plug it in the same.

And there will be some sort of deployment framework, with people deploying stuff and checking stuff, with data in databases or other persistence mediums. Your code logic? Doesn't care.

Imposter syndrome

Does this sound like a pipe dream that a snake oil peddler is trying to sell you? Let me tell you that the only reason you are not working like that now is because someone though it was too complicated and decided to cut corners. And they have been paying for it ever since, as well as you.

The only proven way of solving complex problems is Divide and Rule. Life is complex and real problems, too. Separation of Concerns, Inversion of Control, Domain Boundaries are the tools you use to break any problem into smaller manageable pieces. And that brings us back to interview questions and pointless algorithms.

When you go to a code test, you are the algorithm. They give you some input and an expected output and check to see if your internal rules are up to the task. Of course you could google for an easy solution. More than that, what kind of employee would you be if whenever the boss asked for something you would build it from scratch without seeing what others did? What hubris to believe that you could know the answer better than anyone else without even checking!

Test succeeded

The conclusion of this stream (heh!) of consciousness is that once you realize the algorithmic nature of any problem (once you abstract every interface with reality), you can see the actual value of being proficient in writing one. You might start with sorting and fizzbuzz and other bullcrap like that, but they are just steps on a larger ladder that will eventually make sense, just like learning the letters of the alphabet prepared you to read to the end of this post. Also, if you are trying to get a job as a book editor and the HR person is asking you if you know all the letters of the alphabet, maybe you don't want to work there.

P.S.

The links in this article are important, especially if you are a just beginning your journey as a developer. Check out the concepts there and learn to use them in your life, it will get a whole lot easier!

and has 0 comments

The point of regular expression character classes is to simplify your expressions, but they can introduce subtle bugs or efficiency issues.

Let's check out this StackOverflow answer to question \d less efficient than [0-9]

\d checks all Unicode digits, while [0-9] is limited to these 10 characters. For example, Persian digits, ۱۲۳۴۵۶۷۸۹, are an example of Unicode digits which are matched with \d, but not [0-9].

This makes sense, only it has never occurred to me until this very moment. I would never use a [0-9] notation and I would replace it with a \d if found in code.

What does that mean?

One simple consequence of such a class would be performance: searching for a large list of characters is less efficient. Another would be introducing the possibility for bugs or even malicious attacks. Let's see the code for a calculator that adds two numbers. It's a silly piece of code, but imagine that a more complex one would take the user content and save it into a database, try to process it or display it.

static void Main(string[] args)
{
    Console.InputEncoding = Encoding.Unicode;
    var firstNumber = GetNumberString();
    var secondNumber = GetNumberString();
    Console.WriteLine("Sum = "+(int.Parse(firstNumber) + int.Parse(secondNumber)));
}

private static string GetNumberString()
{
    string result=null;
    var isNumber = false;
    while (!isNumber)
    {
        Console.Write("Enter a number: ");
        result = Console.ReadLine();
        isNumber = Regex.IsMatch(result, @"^\d+$");
        if (!isNumber)
        {
            Console.WriteLine($"{result} is not a number! Try again.");
        }
    }
    return result;
}

This will try to get numbers as a string and test it using the regular expression ^\d+$, which means the string has to consist of one or more digits. Note that I had to set the console input encoding to Unicode in order to be able to paste Persian numbers. This code works fine until I use Arabic or Persian digits, where it breaks in the int.Parse method. Using ^[0-9]$ as the regular expression pattern would solve this issue.

Same issue will occur with \w (warning: \w is letters AND digits) and [a-zA-Z] (or just [a-z] and using RegexOptions.IgnoreCase).

If one uses code to determine the number of matches for each regular expression pattern

var regexPattern = @"\d";
var nr = 0;
for (int i = 0; i < ushort.MaxValue; i++)
{
    string str = Convert.ToChar(i).ToString();
    if (Regex.IsMatch(str, regexPattern))
        nr++;
}
Console.WriteLine(nr);

we get this:

  • for \d : 370
    • ALL digits
  • for \w : 50320
    • ALL word characters (including digits) 
  • for [^\W\d] : 49950
    • ALL word characters, but not the digits 
  • for \p{L} : 48909
    • ALL letters
  • for [A-Za-z] : 52
    • letters from a to z
  • for [0-9] : 10
    • digits from 0 to 9

I hope this helps.

and has 0 comments

Let's start with a simple requirement and the obvious first draft of the code. The requirement is "build a method that receives a string and writes to the console a URL using that string as a parameter".

The obvious first attempt and working in every version of C# would be:

private static void ShowUrl(string something)
{
    var url = "https://siderite.dev/blog/search/formattablestring?param1="+something;
    Console.WriteLine(url);
}

But then you get some problems. You want to use a parameter that has strange characters in it, like an email, another URL, arithmetic symbols, etc. So you realize that you need to use an URL encode class. Next version is:

private static void ShowUrl(string something)
{
    var url = "https://siderite.dev/blog/search/formattablestring?param1="+Uri.EscapeDataString(something);
    Console.WriteLine(url);
}

Now that works for a second. One might argue about the difference between System.Web.HttpUtility.UrlEncode, System.Net.WebUtility.UrlEncode and System.Net.Uri.EscapeDataString. Yet, his is not the post to do that. Follow the above links for more information.

Then someone decides to use a null for the parameter and you get a ArgumentNullException and you rage in frustration "This is complicated and ugly! The first version looked much better and handled nulls, too. And now I have to add this long Uri.EscapeDataString to every URL parameter in every URL building code I write and also check for null!".

But... what if you could write the method just like the first version and get rid of every problem?

First of all, let's get rid of that plus sign and use interpolated strings. They've been around for awhile:

private static void ShowUrl(string something)
{
    var url = $"https://siderite.dev/blog/search/formattablestring?param1={something}";
    Console.WriteLine(url);
}

Now, this has the same problem of the first version: no URL encoding. And you don't want to add an escape function to every parameter (imagine there would be 10 parameters in this URL). How about we use the fact that the URL is an interpolated string?

Check out this code:

private static void ShowUrl(string something)
{
    var url = UrlHelper.Url($"https://siderite.dev/blog/search/formattablestring?param1={something}");
    Console.WriteLine(url);
}

It uses an UrlHelper class to fix the problems with the URL in the string we generate. Or is it a string? I was writing a long time ago a post about FormattableString and how I didn't see a real use scenario for it. Well, this is it! Let's see what UrlHelper looks like:

public static class UrlHelper
{
    public static string Url(FormattableString url)
    {
        return string.Format(
            url.Format, 
            url.GetArguments()
                .Select(a => Uri.EscapeDataString(a?.ToString()??""))
                .ToArray());
    }
}

The Url method receives not a string, but a FormattableString. When an interpolated string is used as a FormattableString, it gives the developer access to a Format string and a list of arguments in GetArguments. In order to convert it to a string, one must only do String.Format(s.Format,url.GetArguments()).  In our case, the Format property will have the value "https://siderite.dev/blog/search/formattablestring?param1={0}" and the arguments list will contain one value: the value of the something parameter.

Therefore, the Url method will be able to format the string, but first URL encode every single parameter in it.

I admit, this might not be the most readable code in the world, which is my pet peeve with FormattableString. Reading the ShowUrl method you have no clue that UrlHelper.Url receives a FormattableString as parameter. One might even look at that string and say "Hey, wait a minute! That's a bug waiting to happen!" and then proceed to fix it. Perhaps the name of the method could be made more intuitive like EncodeUrlParameters.

But wait! We can do better. I don't know how it might help in the future, but perhaps someone might want to process the parameters of the URL further. By returning a string we eliminate some of the information of the incoming parameter and we don't want to do that.

Also, careful people will notice that using String.Format introduces a subtle bug (or feature): we format the string without specifying a culture. This might be fine, using the current one by default, but it might also cause some issues. The FormattableString class does provide the static CurrentCulture and Invariant methods and, of course, the ToString method would work just fine as well, but then we lose the ability to process the parameters.

So here is the final version of the UrlHelper class:

public static class UrlHelper
{
    public static FormattableString EncodeUrlParameters(FormattableString url)
    {
        return FormattableStringFactory.Create(
            url.Format,
            url.GetArguments()
                .Select(a => Uri.EscapeDataString(a?.ToString() ?? ""))
                .ToArray());
    }
}

By using FormattableStringFactory from System.Runtime.CompilerServices we get a FormattableString as an argument and we return one, with parameters URL encoded. Now, if the result of the method is used as a string, it will be automatically handled by ToString and if it will be used as a FormattableString it will contain all the information provided by the original parameters.

Hope that helps!

Bonus time! There's more!

What if you could make this behavior built in by introducing a new type? Methods from, let's say, a REST client class could use FormattableStrings as URL parameters. But what if we could specify the type of the parameters and get the implicit (hint, hint!) result already URL encoded?

public class UrlString
{
    private FormattableString _formattableString;

    public UrlString(FormattableString formattableString)
    {
        _formattableString = formattableString;
    }

    public static implicit operator FormattableString(UrlString urlString)
    {
        if (urlString == null) return null;
        return UrlHelper.EncodeUrlParameters(urlString.ToFormattableString());
    }

    public static implicit operator string(UrlString urlString)
    {
        if (urlString == null) return null;
        return ((FormattableString)urlString).ToString();
    }

    public static implicit operator UrlString(FormattableString formattableString)
    {
        return new UrlString(formattableString);
    }

    private FormattableString ToFormattableString()
    {
        return _formattableString;
    }
}

This UrlString class will implicitly be converted into a FormattableString or a string and a FormattableString will be converted into a UrlString. So now your code might look like this:

// used like this
RestClient.Get($"https://test.com?x={something}");

// this method does not URL encode anything
public RestResponse Get(string url) {
  ...
}

// this method does URL encode everything, just by changing the type
public RestResponse Get(UrlString url) {
  ...
}

Intro

Dependency injection is baked in the ASP.Net Core projects (yes, I still call it Core), but it's missing from console app templates. And while it is easy to add, it's not that clear cut on how to do it. I present here three ways to do it:

  1. The fast one: use the Worker Service template and tweak it to act like a console application
  2. The simple one: use the Console Application template and add dependency injection to it
  3. The hybrid: use the Console Application template and use the same system as in the Worker Service template

Tweak the Worker Service template

It makes sense that if you want a console application you would select the Console Application template when creating a new project, but as mentioned above, it's just the default template, as old as console apps are. Yet there is another default template, called Worker Service, which almost does the same thing, only it has all the dependency injection goodness baked in, just like an ASP.Net Core Web App template.

So start your Visual Studio, add a new project and choose Worker Service:

It will create a project containing a Program.cs, a Worker.cs and an appsettings.json file. Program.cs holds the setup and Worker.cs holds the code to be executed.

Worker.cs has an ExecuteAsync method that logs some stuff every second, but even if we remove the while loop and add our own code, the application doesn't stop. This might be a good thing, as sometimes we just want stuff to work until we press Ctrl-C, but it's not a console app per se.

In order to transform it into something that works just like a console application you need to follow these steps:

  1. inject an IHost instance into your worker
  2. specifically instruct the host to stop whenever your code has finished

So, you go from:

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;

    public Worker(ILogger<Worker> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
            await Task.Delay(1000, stoppingToken);
        }
    }
}

to:

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;
    private readonly IHost _host;

    public Worker(ILogger<Worker> logger, IHost host)
    {
        _logger = logger;
        _host = host;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        Console.WriteLine("Hello world!");
        _host.StopAsync();
    }
}

Note that I did not "await" the StopAsync method because I don't actually need to. You are telling the host to stop and it will do it whenever it will see fit.

If we look into the Program.cs code we will see this:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}

I don't know why they bothered with creating a new method and then writing it as an expression body, but that's the template. You see that there is a lambda adding dependencies (by default just the Worker class), but everything starts with Host.CreateDefaultBuilder. In .NET source code, this leads to HostingHostBuilderExtensions.ConfigureDefaults, which adds a lot of stuff:

  • environment variables to config
  • command line arguments to config (via CommandLineConfigurationSource)
  • support for appsettings.json configuration
  • logging based on operating system

That is why, if you want these things by default, your best bet is to tweak the Worker Service template

Add Dependency Injection to an existing console application

Some people want to have total control over what their code is doing. Or maybe you already have a console application doing stuff and you just want to add Dependency Injection. In that case, these are the steps you want to follow:

  1. create a ServiceCollection instance (needs a dependency to Microsoft.Extensions.DependencyInjection)
  2. register all dependencies you want to use to it
  3. create a starting class that will execute stuff (just like Worker above)
  4. register starting class in the service collection
  5. build a service provider from the collection
  6. get an instance of the starting class and execute its one method

Here is an example:

class Program
{
    static void Main(string[] args)
    {
        var services = new ServiceCollection();
        ConfigureServices(services);
        services
            .AddSingleton<Executor,Executor>()
            .BuildServiceProvider()
            .GetService<Executor>()
            .Execute();
    }

    private static void ConfigureServices(IServiceCollection services)
    {
        services
            .AddSingleton<ITest, Test>();
    }
}

public class Executor
{
    private readonly ITest _test;

    public Executor(ITest test)
    {
        _test = test;
    }

    public void Execute()
    {
        _test.DoSomething();
    }
}

The only reason we register the Executor class is in order to get an instance of it later, complete with constructor injection support. You can even make Execute an async method, so you can get full async/await support. Of course, for this example appsettings.json configuration or logging won't work until you add them.

Mix them up

Of course, one could try to get the best of both worlds. This would work kind of like this:

  1. use Host.CreateDefaultBuilder() anyway (needs a dependency to Microsoft.Extensions.Hosting), but in a normal console app
  2. use the resulting service provider to instantiate a starting class
  3. start it

Here is an example:

class Program
{
    static void Main(string[] args)
    {
        Host.CreateDefaultBuilder()
            .ConfigureServices(ConfigureServices)
            .ConfigureServices(services => services.AddSingleton<Executor>())
            .Build()
            .Services
            .GetService<Executor>()
            .Execute();
    }

    private static void ConfigureServices(HostBuilderContext hostContext, IServiceCollection services)
    {
        services.AddSingleton<ITest,Test>();
    }
}

The Executor class would be just like in the section above, but now you get all the default logging and configuration options from the Worker Service section.

Conclusion

What the quickest and best solution is depends on your situation. One could just as well start with a Worker Service template, then tweak it to never Run the builder and instead configure it as above. One can create a Startup class, complete with Configure and ConfigureServices as in an ASP.Net Core Web App template or even start with such a template, then tweak it to work as a console app/web hybrid. In .NET Core everything is a console app anyway, it's just depends on which packages you load and how you configure them.

and has 0 comments

  Mirage is inspired by the "Years of Lead" in Morocco's 1960s history and its underlying message about the terrors of colonialism is quite important. At first I thought it was inspired by the plight of Arabs in Palestine, so it's also very timely. That is why it pains me to say that I couldn't go more than several chapters in. The writing is amateurish, the lead teen character inconsistent and annoying and this is clearly a YA book written by a woman for other women.

  That may sound misogynistic, but everyone who has ever hunted for a good book to read knows what I mean: you get to something that has rave recommendations, raised to the level of masterpiece by a few articles, but then when you start reading and you look closer at those reviews you see that they are mostly from women writing those five star animated GIF capital letter emoji filled things. And all the men give two stars and wonder how did they get to read the book in the first place, just like you.

  I don't want to be unfair to Somaiya Daud - this is her debut novel and I am sure her writing will get better with time - but for me reading through the rest of the book and knowing that it's yet another trilogy in the making, so having to wait even more to even get to the end of the story, was too much. It also addresses issues of personal helplessness, which is probably my Achilles' heel. If I ever want to get to those good books that I want to find, I have to fail fast and cut my losses early.

  Bottom line: I couldn't even begin to start reading the book. A combination of subject, debut writing style and aggressive and misleading advertising made me abandon it immediately.

and has 2 comments

  Half a year ago I was writing a piece about how the system is stacked against you, no matter where on the ladder you are. Nobody cares about you! was part depression and part experience, because I have worked in corporations most of my career and that's exactly what happens in real life. This post will not be in the "What's Siderite going to say to make us hate life and kill ourselves" category, though. Quite the opposite. I am going to tell you what the logical consequence of that dreary article is - and it's good!

  Think about it! Are there nice things in the world? And I am not talking about love, sunrises and cute kittens, but about human acts and artefacts. The answer is yes, or you are a lot more depressed than I've ever been. So, if the world is configured to not care about you or about anyone, if the logical best strategy is to do just as much as it is absolutely required and fake the rest, why is there human beauty out there?

  The answer is: every good and beautiful man made thing that you see in the world is by someone doing more than they were asked to do. It's a simple sentence, but a powerful reality. Every day people, like and unlike you and me, are defying the boring order of the universe to create beauty and to better the world. Let's say you play a game made by a big game company and you are enjoying it. - maybe not the entire game either, just some portion of it - I can assure you that is not the consequence of the money poured in it, but of some person who did a little more than the bare minimum. If you use a program, a boring one, like Office something, and you find a feature that blows your mind, be convinced that no one asked for it specifically and someone actually made an extra effort to put it there. If you like the way the handle of the knife feels in your hand when you're slicing bread, same.

  And yes, there is the theory that every act of altruism comes from selfishness, and you can abstract everything to mean anything when it involves humans, but I am not talking about people who want to make the world better or selfless angels who want to make others happy. I am talking here of the simple fact of doing more than necessary just because you want to. And I am not talking about some kind of artsy philosophical method of improving everything and sparking joy, but about at least one, just one act that is invested with a bit of a human person. They do what they were asked to, paid to, coerced to, bullied to, begged to, then they make another step. Maybe it's inertia, maybe it's not knowing when to stop or not knowing what's good for them, but they did it and in the act imbued something with a piece of their soul.

  OK, I know that this is more of a "diamond in the mud" category rather than a positive message, but have you ever considered that even the smallest joys in life may come from the acts of rebellion of others? Maybe it's not a diamond, maybe it's a shitty opal, but knowing that you found it in the mud gives it immense relative value. Finding the ugliness, the stupid, the petty, the outrageous is easy. Seeing something beautiful and knowing it grew out of this is rare and valuable.

and has 0 comments

  We have been told again and again that our code should be split into smaller code blocks that are easy to understand and read. The usual example is a linear large method that can easily be split into smaller methods that just execute one after the other. But in real life just selecting a logical bit of our method and applying an Extract Method refactoring doesn't often work because code rarely has a linear flow.

  Let's take a classic example of "exiting early", another software pattern that I personally enjoy. It says that you extract the functionality of retrieving some data into a method and, inside it, return from the method as soon as you fail a necessary condition for extracting that data. Something like this:

public Order OrderCakeForClient(int clientId) {
  var client = _clientRepo.GetClient(clientId);
  if (client == null) {
    _logger.Log("Client doesn't exist");
    return null;
  }
  var preferences = _clientRepo.GetPreferences(client);
  if (preferences == null) {
    _logger.Log("Client has not submitted preferences");
    return null;
  }
  var existingOrder = _orderRepo.GetOrder(client, preferences);
  if (existingOrder != null) {
    _logger.Log("Client has already ordered their cake");
    return existingOrder;
  }
  var cake = _inventoryRepo.GetCakeByPreferences(preferences);
  if (cake == null) {
    cake = MakeNewCake(preferences);
  }
  if (cake == null) {
    _logger.Log("Cannot make cake as requested by client");
    return null;
  }
  var order = _orderRepo.GenerateOrder(client, cake);
  if (order == null) {
    _logger.Log("Generating order failed");
    throw new OrderFailedException();
  }
  return order;
}

This is a long method that appears to be linear, but in fact it is not. At every step there is the opportunity to exit the method therefore this is like a very thin tree, not a line. And it is a contrived example. A real life flow would have multiple decision points, branching and then merging back, with asynchronous logic and so on and so on.

If you want to split it into smaller methods you will have some issues:

  • the most of the code is not actual logic code, but logging code - one could make a method called getPreferences(client), but it would just proxy the _clientRepo method and gain nothing
  • one could try to extract a method that gets the preferences, logs and decides to exit - one cannot do that directly, because you cannot make an exit decision in a child method

Here is a way that this could work. I personally like it, but as you will see later on, it's not sufficient. Let's encode the exit decision as a boolean and get the information we want as out parameters. Then the code would look like this:

public Order OrderCakeForClient(int clientId) {
  if clientExists(clientId, out Client client)
    && clientSubmittedPreferences(client, out Preferences preferences)
    && orderDoesntExist(client, preferences, out Order existingOrder)
    && getACake(preferences, out Cake cake) {
    return generateOrder(client,cake);
  }
  return existingOrder;
}

private bool clientExists(clientId, out Client client) {
  client = _clientRepo.GetClient(clientId);
  if (client == null) {
    _logger.Log("Client doesn't exist");
    return false;
  }
  return true; 
}

private bool clientSubmittedPreferences(Client client, out Preferences preferences) {
  preferences = _clientRepo.GetPreferences(client);
  if (preferences == null) {
    _logger.Log("Client has not submitted preferences");
    return false;
  }
  return true;
}

private bool orderDoesntExist(Client client, Preferences preferences,
                               out Order existingOrder) {
  existingOrder = _orderRepo.GetOrder(client, preferences);
  if (existingOrder != null) {
    _logger.Log("Client has already ordered their cake");
    return false;
  }
  return true;
}

private bool getACake(Preferences preferences, out Cake cake)
  cake = _inventoryRepo.GetCakeByPreferences(preferences);
  if (cake == null) {
    cake = MakeNewCake(preferences);
  }
  if (cake == null) {
    _logger.Log("Cannot make cake as requested by client");
    return false;
  }
  return true;
}

private Order generateOrder(Client client, Cake cake)
  var order = _orderRepo.GenerateOrder(client, cake);
  if (order == null) {
    _logger.Log("Generating order failed");
    throw new OrderFailedException();
  }
  return order;
}

Now reading OrderCakeForClient is a joy! Other than the kind of weird assignment of existingOrder in a condition method, which is valid in C# 7, but not that easy to read, one can grasp the logic of the method from a single glance as a process that only runs if four conditions are met.

However, there are some problems here. One of them is that the out syntax only works for non-async methods and it is generally frowned upon these days. The method assumes a cake can just be made instantly, when we know it takes time, care, effort and kitchen cleaning. Also, modern code rarely features synchronous database access.

So how do we fix it? The classic solution for getting rid of the out syntax is to create custom return types that contain everything the method returns. Let's try to rewrite the method with async in mind:

public async Task<Order> OrderCakeForClient(int clientId) {
  var clientExistsResult = await clientExists(clientId);
  if (!clientExistsResult.Success) return null;
  var orderDoesntExistResult = await orderDoesntExist(client, preferences)
  if (!orderDoesntExistResult.Success) return orderDoesntExistResult.Order;
  var getACakeResult = await getACake(preferences);
  if (!getACakeResult.Success) return null;
  return generateOrder(client,cake);
}

private async Task<ClientExistsResult> clientExists(clientId) {
  client = await _clientRepo.GetClient(clientId);
  if (client == null) {
    _logger.Log("Client doesn't exist");
    return new ClientExistsResult { Success = false };
  }
  return new ClientExistsResult { Client = client, Success = false }; 
}

// the rest ommitted for brevity

Wait... this doesn't look good at all! We wrote a ton of extra code and we got... something that is more similar to the original code than the easy to read one. What happened? Several things:

  • because we couldn't return a bool, he had to revert to early exiting - not bad in itself, but adds code that feels to duplicate the logic in the condition methods
  • we added a return type for each condition method - extra code that provides no extra functionality, not to mention ugly
  • already returning bool values was awkward, returning these result objects is a lot more so
  • the only reason why we needed to return a result value (bool or something more complex) was to move the logging behavior in the smaller methods

"Step aside!" the software architect will say and quickly draw on the whiteboard a workflow framework that will allow us to rewrite any flow as a combination of classes that can be configured in XML. He is dragged away from the room, spitting and shouting.

The problem in the code is that we want to do three things at the same time:

  1. write a simple, easy to read, flow-like code
  2. make decisions based on partial results of that code
  3. store the partial results of that code

There is a common software pattern that is normally used for flow like code: the builder pattern. However, it feels unintuitive to use it here. First of all, the builder pattern needs some masterful code writing to make it work with async/await. Plus, most people, when thinking about a builder, they think of a separate reusable class that handles logic that is independent from the place where it is used. But it doesn't need to be so. Let's rewrite this code using a builder like logic:

public async Task<Order> OrderCakeForClient(int clientId)
{
    SetClientId(clientId);
    await IfClientExists();
    await IfClientSubmittedPreferences();
    await IfOrderDoesntExist();
    await IfGotACake();
    return await GenerateOrder();
}

private bool _continueFlow = true;
private int _clientId;
private Client _client;
private Preferences _preferences;
private Order _existingOrder;
private Cake _cake;

public void SetClientId(int clientId)
{
    _clientId = clientId;
    _existingOrder = null;
    _continueFlow = true;
}

public async Task IfClientExists()
{
    if (!_continueFlow) return;
    _client = await _clientRepo.GetClient(_clientId);
    test(_client != null, "Client doesn't exist");
}

public async Task IfClientSubmittedPreferences()
{
    if (!_continueFlow) return;
    _preferences = await _clientRepo.GetPreferences(_client);
    test(_preferences != null, "Client has not submitted preferences");
}

public async Task IfOrderDoesntExist()
{
    if (!_continueFlow) return;
    _existingOrder = await _orderRepo.GetOrder(_client, _preferences);
    test(_existingOrder == null, "Client has already ordered their cake");
}

public async Task IfGotACake()
{
    if (!_continueFlow) return;
    _cake = await _inventoryRepo.GetCakeByPreferences(_preferences)
        ?? await MakeNewCake(_preferences);
    test(_cake != null, "Cannot make cake as requested by client");
}

public async Task<Order> GenerateOrder()
{
    if (!_continueFlow) return _existingOrder;
    var order = await _orderRepo.GenerateOrder(_client, _cake);
    if (order == null)
    {
        _logger.Log("Generating order failed");
        throw new OrderFailedException();
    }
    return order;
}

private void test(bool condition, string logText)
{
    if (!condition)
    {
        _continueFlow = false;
        _logger.Log(logText);
    }
}

No need for a new builder class, just add builder like methods to the existing class. No need to return the instance of the class, since it's only used inside it. No need for chaining because we don't return anything and chaining with async is a nightmare.

The ugly secret is, of course, using fields of the class instead of local variables. That may add other problems, like multithread safety issues, but those are not in the scope of this post.

I've shown a pretty stupid piece of code that anyway was difficult to properly split into smaller methods. I've demonstrated several ways to do that, the choice of which depends on the actual requirements of your code. Hope that helps!

and has 0 comments

  I have heard about Jack Kerouac and his most famous book On the Road for as long as I can remember, but I had never read it until now. I did watch the 2012 movie with the same name, though, and I gave it the highest rating. I still believe Garrett Hedlund was amazing in it and that the guy needs more great roles like that. So, while whole books have been written about the Beat Generation, Jack Kerouac and his friends and about On the Road itself, what did I, greatest book critic ever, think of it?

  I liked it. I can say that parts of it were lovely and parts of it boring. But consider this: Kerouac wrote this as a "scroll", based on a stream of thoughts randomly thrown on whatever paper he could find on his travels, shaped by whatever place he was in and what mood he was having and which people he was with and what substances coursed through his body. The scroll itself is twice as big as the book he eventually published and On the Road is considered part of the Duluoz Legend series, which spans 13 books. The thing to look for in his writing cannot be about specific details, but about the overall philosophy, the experience.

  That is why I can safely and with certainty say: I will not read the scroll version, I liked the book, but I loved the movie. And while this is not a review of the film, I did notice that many of its critics were mainly focused on "it's not like the book". Gentlemen, if the film would have been about other people doing other things, but in the same spirit as the book, it would still have been On the Road and just as entertaining. Because, while this is based on actual people and actual experiences, the specifics are quite irrelevant. Once you capture the spirit of the thing, the rest is just filler.

  So what is the book about? Jack and his buddy Dean spend the entire time moving from New York to San Francisco and back, using their own cars, car sharing, hitching, jumping on trains, buses, or however they could, enjoying each other's company and the feeling of being on the road and meeting interesting people and living life at its fullest. The film has a great female cast, but you will notice that they are barely doing anything. They are there in the background, because while the story contains them, it is not focused on them. It's even more so in the book, where characters jump in and out of the story: travel companions, drink and drug buddies, random sex, true love, marriages, children, people who let them sleep in their houses with or without pleasure. And while everything is told from the perspective of the writer and Dean has the next more important role, even then you cannot say the story is about them.

  The effect that both book and movie had on me was quite an antisocial one. They made me dream of travelling light, experiencing all kinds of adventures while caring about nothing and nobody, just living in the moment. It's a nice fantasy, one that breaks easily under the weight of my own nature and the oppressive organization of the present, but nice nonetheless. On the Road gives us a glimpse of what was gained and what got lost in 70 years from the perspective of people doing the living back then. There is no hero, no villain, no moral to the story and no mystery to solve. Just people being as free as the world lets them to.

Bottom line: not the best book that I have ever read, but also great, fresh, honest, worth reading, with characters worth knowing. It is important to know that in order to get to the curated, safe, stale world we live in, others had to try all kinds of other things, that freedom is something you feel rather than something given to you. This is a fantasy and an autobiography all at once. That's the part that I loved most.

and has 1 comment

  I am watching Star Trek: The Next Generation, a show that I have loved since I was a child and was watching obsessively again and again at that time. Yet as I grew older (and hopefully wiser) and with full knowledge of TV and movie culture since then, I see many new things in this show that I was unable at the time of my youth.

  Next Generation is, on the surface, a story about a wonderful future in which humanity has somehow distilled its best qualities and created a post-scarcity utopia that anyone can enjoy and in which everybody can thrive. People are intelligent, educated, passionate, considerate, moral, loyal and dutiful. They don't even have money anymore!  In a show made in 1987, computers were there just to do the bidding of humans, with no creativity or decision power. Security was just a matter of choosing a good password any anyone could access almost everything given a few minutes.

   However this was not unintentional. The vision of the show was focused on "humanity at its best" and so it could never be outmatched by algorithms, machines or cold calculation. And the most beautiful thing of all is Starfleet, an organization dedicated to knowledge and exploration, diplomacy and discovery, where everyone who is insanely qualified can find their place amongst the stars, happy to serve their duty in a heavily structured navy that is at the same time diverse, inclusive, quaint and strict.

  It surely inspired me when I was a child, but now I start seeing things that I couldn't then. The judgement of anyone who is different while expressing views of total tolerance, for example. And I am not talking about species that were particularly designed to be repugnant or immoral, like the Ferengi, but about people. Barclay, for example, a brilliant engineer that can't find the confidence to assert himself is ridiculed for his addiction to the holodeck, called Broccoli behind his back, almost transferred because he is not expressing himself as expected and punctual enough, yet embraced when he saves the day. At that time it felt like an honest mistake that the crew wished to resolve and in the end did. But what if he didn't save the day? In another episode, Riker refuses yet another promotion to captain and an admiral asserts his career will suffer, as other young and brilliant people aim higher than him, which makes him seem a risk avoider. And in yet another episode Picard goes back in time to behave more rationally in his youth, only to find himself in the present relegated to a role of lieutenant that is not taken seriously when asking for advancement because he had always chosen the safe path.

  All this went over my head when I was young, but now it sounds a lot just like the most toxic of corporate cultures. You either fit in and play happy or you are pushed out to a life that no one even mentions. You can tend plants in your garden for the rest of your life, because if you didn't fall in line with the office rulebook, you won't be working there. That doesn't sound like a utopia for me, but a dystopia, a world ruled by churches that expect, with kindness, that you obey the rules exactly, both in your work life and your personal one, move in a certain way, behave in a certain way, talk in a certain way and navigate topics of conversation carefully. In fact, many a time in Star Trek, the line between work and personal life was explicitly rejected. In one episode Deanna Troi shouts to her mother that the crew of the Enterprise is her family and there lies her life. In many others Picard refuses to go on vacation and even there he is reading heavy stuff that will help him at his work.

  The principles spouted by the actors in the show are also routinely broken by actions motivated with sophistry and dramatism. But not just anyone can break those principles. One of the main cast can do it, and always under the benevolent yet strict oversight of the captain. And in case you want to "play the game" and "fake it till you make it" there is always counselor Troi to invade your privacy and broadcast you real emotions to the captain.

  And I admit that I am a corporate guy, enjoying the relative safety and monetary comfort by sacrificing some of my principles and remaining relevant to my level of employment. The truth is that the same environment can be a blessing for some and a nightmare for others. Yet the problem is not the rules themselves, but how static and rigid they are. If one can either choose one way to behave or the other, with no overlap and a large gap between the two, there is little chance for people from a group to move to the other. Without that mobility things stagnate and die and that is exactly my own experience in real life corporations.

  I am not trying to criticize The Next Generation here. It was an amazing show that churned 25 episodes of good storytelling and decent acting per year for seven years in a row and which generated two spinoffs: DS9 and Voyager. Compare this with today's Star Trek: seasons of 13 episodes with three times the budget per episode (adjusted for inflation) and a linear storyline that is neither original nor well thought. What I am trying to say is that under the veneer of a beautiful bright future, one that Gene Roddenberry imagined with the best of intentions, the details belie the influence of the real world and of how people really function. It's a wonderful example of how the same concepts and the same words look great at one time and less so after you experience them.

  Bottom line: I think Gene's vision was great and the future imagined by him puts the present to shame, yet I am sure I would have had a very hard time adapting to life on the Enterprise. Perhaps I would have been the guy at the teleporter station, who obviously has no reason to do anything there unless when orbiting or approaching another ship, doing his job in a place with no windows or chairs and that somehow everyone knows by name. Or the cadet who always finds ways of optimizing things, but can't navigate the complicated rules of political correctness or the chain of command when wanting to express them. Or Barclay. Probably Barclay.

and has 1 comment

Intro

  Labels. Why do we need them? At first it seems like a natural outcome of people trying to understand their surroundings: good/bad, light/dark, wet/dry, etc. It makes sense to start with a simplified model of reality when it is all brand new. However, as we grow, we soon realize that God/Devil is in the details, that taste is more a matter of subtlety than brute strength and that labels, as useful as they have been, sometimes need throwing away. As the old adage says: a beginner needs to learn the rules, an expert knows all the rules, a master knows when to break the rules.

  So how come, with such a general and all encompassing principle, proven many times over millennia, we still cling to labels? And not only to understand the world around, but to understand ourselves and, ultimately, define ourselves? Not only internally, but externally, as a society? Codifying them in laws and unspoken yet strongly enforced rules?

An innocent example

  Let me give you an example. When we enter adolescence we start getting sexually attracted by other people. So this imaginary adolescent (A) likes one girl, then another, then another. After three girls he decides, with the tacit and active approval of his relatives and friends, he is straight. Another imaginary adolescent (B) likes guys, so he's gay. And now, so that we can identify the usefulness of these concepts, we add a third adolescent (C). A sexy young stud that likes... girls, let's say, and has managed to not only like them, but successfully have sexual encounters with them. He has had sex with 20 girls. So tell me, who is more like who in this triangle of adolescents? How do you split this hyperplane of three people into two parts? How do you cluster these people into two groups? Because to me it seems that A and B are far more alike than any of them is similar to C. Moreover, is the sexual attraction pattern that has been established in early adolescence even stable? What happens if the next person A likes is another guy? Is he bisexual now? By how much? Is he 75% hetero?

  Leaving my personal thoughts aside, can anyone tell me what these labels are for? Because if you find yourself sexually attracted by someone, then for sure you don't need a statistical model to analyze that. Is it for the benefit of the other person? "Sorry, but I am straight", which would translate to something like "Oh, I have to tell you that, based on the statistical evidence for sexual attraction I have gathered, I seem to be exclusively attracted to girls. So don't take it personally. I have nothing against gay people, I just have a biological reason to reject any of your advances". Does that sound in any way useful? Especially since we are being taught that one does not refute another's reasons for sexual or romantic rejection, that they have the given right to unilaterally refuse, regardless of any rational reason.

  One might argue that these labels are like armor to define and strengthen the identity of people. You don't just observe you are straight or gay, you define yourself as such, thus avoiding confusion, minimizing internal conflict and adhering to a community. Then, collectively, one can fight the inevitable "You are weird and must die" situation in which all people find themselves in, at one time or the other, when facing people different from themselves. But then, isn't clearly defining a group of people painting a target on their back? Look at the LGBTQ... whatever community. They are actively combatting the discrimination and disrespect that is thrown at them by finely defining the specific sexual group they belong to, then bundling them all together into a community of completely different people. Because they have a common enemy, you see, the cis people (a term they had to invent to define the majority of people, so they don't have to define themselves as not normal). So if I am gay, for example, I am the G person, not the B person, which also accepts sexual encounters with people of the other sex. Why is that important?

  Why can't I fuck whoever I want to fuck, assuming they agree? Why do I need a label which will restrict my choices in the future?

  People managed to somehow debate gender now. And not in terms of "why does it matter?" but in "you didn't define it correctly. It's spelled Phemail, as per the new gender atlas of 2022!"

A less divisive topic

  And what I am saying is not related just to sexuality. Say race, to take something less divisive. Am I White? How do you know? Because the color of my skin? What if you found out that my parents are both Black and I have a skin condition? Is it ancestry, then? The proportion of genetic code from various (very vaguely defined) groups of people in my own? Then we get to the same thing: if my grandfather is Black, am I 25% Black? What if he was Japanese? What the hell does that matter anyway? Why do we need labels like "Caucasian", "non-White", "person of color", "African American"? Am I a European Romanian as opposed to a South Asian Romanian because his Indian-like race was enslaved in Europe a bunch of centuries ago? Who needs this crap? Is it to define values for eventual retribution for perceived historical slights? Is race an accounting concept?

  I identify as a software developer. I am more alike people writing software that with the majority of men, Romanians, sun deprived people with terribly white skin, guys who like girls or humans in general. And there are a lot of software people that are nothing like me. Is it a useful identity, then, other than for HR people? I would say no. No one cares anyway, except when meeting new people and they ask what I do, I tell them, then there is that awkward "Oh..." and they go ask someone else.

The hell with it

  And the holy trinity would not be complete without religion. Religion is a concept you choose! It's the only thing you are protected by law to believe despite any evidence and to act accordingly. It is the same as the identity shield portion of race or sexuality, but that's where the buck stops. No one can prove you are a Christian or a Buddhist. It's a completely arbitrary belief system that is codified only when interacting with other people. You do to Church and if they start singing, or doing strange hand gestures, you better know the lyrics and the gestures or they won't look positively on you. It's like the secret handshake of the gang in your neighborhood. But when you are all alone and you think about God, it's sure that you are thinking of it slightly different than any other person in the world. So why do you need the label? Why can't you believe in two gods, hedge your bets so to speak? You go to the mosque and then to the synagogue. Surely double dipping would be a worse sin than not believing in the true God, wouldn't it? And then, what God do you believe in more?

  Even nationality is stupid. Does the place where I was born define me, or maybe the one I lived the most in? It certainly influences my culture, my values and one can statistically infer many things about me from them, but they are just influences on the path of my life. Some may be important, some not, I may have rejected some or grew out of them. Other than administrative and bureaucratic reasons, nationality is again a mere choice!

  I agree with people who choose to define themselves in certain ways. I respect every personal choice as long as it doesn't hurt others. I am not against self-defining. What I am against, though, is about giving social and legal power to these labels. And then to redefine them again and again as times change. Think of the tortuous etymology of the word "antisemite" for example. You want to define yourself, fine! Don't impose it on me, though. "I identify as a serial killer. Please don't disrupt me in observing the rituals of my people and let me stab you!"

So what's your point?

  We live in a time where everybody and their grandmother decry divisiveness, extremism, polarization. It seems to me that if we want to minimize that, we should at least renounce placing people in disjunct boxes. One shouldn't care what my race, religion or sexuality is until it's relevant to some sort of interaction. And if they find out, it shouldn't be any more important than any other trivia about my person. I say fight the entire idea of labeling people, as a general principle, whether you do it to hurt them or to declaratively protect them. And if you want to build an atlas to categorize the weird and beautiful human species, do it from a place of observation, not coercion.

Forget canon

  Which brings me to the last point. Some people religiously defend their belief in ... imaginary characters and stories. You hear stuff like "In reality, Star Trek canon says that...". No. I have watched everything Star Trek. There is no canon. Canon is used in the concept of religious writings, where people arbitrarily decide what part of a religion is correct and for which part one should burn other people for supporting. It has no place in fiction. Good writing needs to be consistent. If it spreads over multiple decades, multiple writers, multiple IP owners and different times, it needs to adapt. You can say that something is stupidly inconsistent or that adapting old ideas to new times sometimes is detrimental to those ideas and you'd better start anew with fresh stuff. You might even call people idiots for the way they chose to do any of these things. What you cannot expect is canon for imagination! If you do, you are only helping lawyers carve out the landscape of human fantasy and parcel out terrain and capital for the people who care the least about your entertainment.

Conclusion

  Exploring a new domain always requires defining labels, as a simplistic model for charting the unknown. People are not a new domain, nor are they unknown. They may be unknowable, but they certainly don't belong in nicely shelved boxes in the warehouse of politicians, accountants or lawyers, people lacking all imagination or passion. If you believe the current model of interacting with the world is wrong, maybe the surest way to fix it is to renounce and denounce the labels that define the model.