and has 0 comments

The Problem


Phew, that's a mouthful. But the issue is that trying to serialize a FileInfo or a DirectoryInfo object with Newtonsoft's Json library in .NET Core fails with a vague exception:
Newtonsoft.Json.JsonSerializationException: Unable to serialize instance of 'System.IO.DirectoryInfo'.
at Newtonsoft.Json.Serialization.DefaultContractResolver.ThrowUnableToSerializeError(Object o, StreamingContext context)
at Newtonsoft.Json.Serialization.JsonContract.InvokeOnSerializing(Object o, StreamingContext context)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.OnSerializing(JsonWriter writer, JsonContract contract, Object value)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)

It doesn't say why it fails, just that a method called ThrowUnableToSerializeError threw um... an unable to serialize error?

The Cause


Looking at the Newtonsoft code, we eventually get to this piece of code:
// serializing DirectoryInfo without ISerializable will stackoverflow
// https://github.com/JamesNK/Newtonsoft.Json/issues/1541
if
(Array.IndexOf(BlacklistedTypeNames, objectType.FullName) != -1)
{
contract.OnSerializingCallbacks.Add(ThrowUnableToSerializeError);
}

Later, another piece of code will execute the serializing callbacks and throw the exception. We can get rid of this functionality, by using a custom contract resolver, like this:
var settings = new JsonSerializerSettings
{
ContractResolver = new FileInfoContractResolver()
};
 
private class FileInfoContractResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
var result = base.CreateContract(objectType);
if (typeof(FileSystemInfo).IsAssignableFrom(objectType))
{
result.OnSerializingCallbacks.Clear();
}
return result;
}
}

Yet now, when trying to serialize, we get the stack overflow exception described in the original Newtonsoft.Json issue. It stems from the difference between the .NET Framework implementation and the .NET Core implementation of ISerializable in FileSystemInfo, which in Core just throws PlatformNotSupportedException. It's still not clear why it goes to a StackOverflowException, probably some conflict with Newtonsoft code, but it's clear Microsoft does not intend to make these classes serializable. If you think about it, those classes suck for so many reasons!

The Solution


So, in order to solve it, we will use a custom JSON converter:
private class FileSystemInfoConverter:JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(FileSystemInfo).IsAssignableFrom(objectType);
}
 
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var jObject = JObject.Load(reader);
var fullPath = jObject["FullPath"].Value<string>();
return Activator.CreateInstance(objectType, fullPath);
}
 
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var info = value as FileSystemInfo;
var obj = info == null
? null
: new
{
FullPath = info.FullName
};
var token = JToken.FromObject(obj);
token.WriteTo(writer);
}
}
And we use it like this:
var settings = new JsonSerializerSettings
{
Converters = new List<JsonConverter>
{
new FileSystemInfoConverter()
}
};
var json = JsonConvert.SerializeObject(dir, settings);
var info = JsonConvert.DeserializeObject<DirectoryInfo>(json, settings);

Why FileInfo and DirectoryInfo suck


The answer of a senior developer to any question should be "Why?" or "Why on Earth or anywhere in the Solar System would you want to do a dumb thing like that?!?!". Why would you want to serialize a directory or file info object? The answer is that you should not. The info objects are defined by only one thing: a path, but they have so much baggage: properties that access the file system, unsafe methods, no interfaces or factory methods that can allow them to be mocked in unit tests. They might look like data objects, but they are not!

Imagine a scenario where you have a list of all the files in your drive. You enumerated them all and now you want to serialize them. Should the serializer save Exists or Length, for example? Because that means it will access the file system for each of them in the process of serialization, leading to a lot of work, propensity to access errors and so on.

Best practices say you should either use some model classes to move around data, like an empty FileSystemInfoModel with Type and FullPath and maybe Attributes or Size properties or whatever you want to save, but that you set yourself as a separate responsibility. And if you want to use the functionality of the Info classes, use System.IO.Abstractions or the new Core IFileProvider abstraction to get implementations of interfaces that you can mock in unit tests.

Tell me what you think.

and has 0 comments

It seems there is a dedicated fan base for the Riyria series that so enjoy the setup that they ignore the quality (or lack thereof) of the writing. The writing style is amateurish at best, the characters are not fleshed out, yet the little building they get is contradicted with impunity whenever the plot requires it, the point of the story of the book has not been revealed after more than half of it, while the plot doesn't make any sense most of the time.

I am sorry, Michael J. Sullivan, but I could only read 60% of The Crown Tower before deciding I will not continue and I will not try any of the other books in the series. For the readers, imagine a story about implausibly competent youngsters that are forced to work together by a kindly old professor for no good reason other than they have to work together. Imagine a prostitute who decides to fight the world and open her own brothel, right across the street from her former pimp and king of the street, but the only concerns she has is how to bribe city officials to give her a business permit. After half of the book in which the characters have barely begun to do any of the activities listed above, nothing really happened, while hints have been placed to imply this is a world where magic exists, goblins, elves, dwarves, gods, yet none of them made an appearance.

I don't understand how stuff like that gets any awards. Is it just because they sell? Toilet paper sells and doesn't win anything! Just... ugh!

and has 0 comments
You remember when you had to write a paper for college and you had the thing that you wanted to say, but then your coordinator told you to make it a chapter, and then add others that are related for context? This book kind of feels like that. In English it is called The Fear Factor, but the Romanian edition calls it "Altruist or being good without reward" (my direct translation, as Good for Nothing didn't feel right, even if it is the title of the book in the UK), showing that even editors didn't really agree with the author on the right way to label it.

Overall, what Abigal Marsh tries to say is simple: our capacity to do good to others without expecting a reward stems from an ancient mammalian mechanism designed to bond mothers to children and it is triggered by our ability to empathize with the fear other feel, while regulated by a network of brain centers, mainly our amygdala and hippocampus using the oxytocin hormone. This takes the book through eight chapters, each kind of separate and which I liked in different measures. The ones describing carefully crafted experiments and their outcomes I liked best, the ones that felt like fillers or the ones affirming that correlation doesn't imply causation then proceeding in describing a lot of correlation less so.

Marsh goes out of her way to portray a positive image of humanity, where most people are generous, empathetic and altruistic. She describes people who aren't capable of it - psychopaths and their amygdala dysfunction, people on the other side of the curve - superaltruists who don't care to whom they do good, they just do it, goes to very interesting experiments and comes with theories about how and why altruism, fear and empathy work. Her conclusion is that our focus on negative things makes us falsely believe things are getting worse, people less trustworthy, when the actual opposite if overwhelmingly true.

Bottom line: I liked the book, but some of the chapters felt forced. I didn't really need the exposition of her beach trip to save the turtles or how much she feared and then appreciated the help of a random guy who looked like a hood thug. Most of the information interesting to me was concentrated in the first chapters, while the last, explaining what to do to become more altruistic and how that improves our well being and filled with international statistical charts on altruism I could have done without entirely. It's not that it wasn't correct or well written, it just felt like an add on that had little to do with the book or, worse, was there just to fill up space.

If you search on TED Talks, you will see the author have a talk there titled Abigail Marsh: Why some people are more altruistic than others.

and has 0 comments
This post starts from a simple question: how do I start a task with timeout? You go to StackOverflow, of course, and find this answer: Asynchronously wait for Task<T> to complete with timeout. It's an elegant solution, mainly to also start a Task.Delay and continue when either task completes. However, in order to cancel the initial operation, one needs to pass the cancellation token to the original task and manually handle it, meaning polluting the entire business code with cancellation logic. This might be OK, yet are there alternatives?

But, isn't there the Task.Run(action) method that also accepts a CancellationToken? Yes, there is, and if you thought this runs an action until you cancel it, think again. Here is what Task.Run says it does: "Queues the specified work to run on the thread pool and returns a Task object that represents that work. A cancellation token allows the work to be cancelled." and if you scroll down to Remarks, here is what it actually does: "If cancellation is requested before the task begins execution, the task does not execute. Instead it is set to the Canceled state and throws a TaskCanceledException exception". You read that right: the token is only taken into account when the task starts running, not while it is actually executing.

Surely, then, there must be a way to cancel a running Task. How about Task.Dispose()? Dispose throws a funny exception if you try it: "System.InvalidOperationException: 'A task may only be disposed if it is in a completion state (RanToCompletion, Faulted or Canceled).'". In normal speech, it means "Fuck you!". If you think about it, how would you abort a task execution? What if it does nasty things, leaves resources occupied, has to clean up after it? The .NET team took the safe path and refused to give you an out of the box unsafe cancelling mechanism.

So, what is the solution? The recommended one is that you pass the token to all methods that can be cancelled and then check inside if cancellation was requested. Of course this only works if
  1. you control what the task does
  2. you can split the operation into small chunks that are either executed sequentially or in a loop so you interrupt their flow
. If you have something like an external process that is being executed, or a long running operation, you are almost out of luck. Why almost? Well, CancellationSource or CancellationToken do not have events, but the token exposes a "wait handle" that you can wait for synchronously. And here it gets funky. Check out an example of a method that executes some long running action and can react to token cancelling:
/// <summary>
/// Executes the long running action and cancels it when needed
/// </summary>
/// <param name="token"></param>
private void LongRunningAction(CancellationToken token)
{
// instantiate a container and keep its reference
var container = new IdentificationContainer();
Task.Run(() =>
{
// wait until the token gets cancelled on another thread
token.WaitHandle.WaitOne();
// this will use the information in the container to kill the action
// (presumably by interrupting external processes or sending some kill signal)
KillLongRunningAction();
});
// this executes the action and populates the identification container if needed
RunLongRunningAction();
}
This introduces some other issues, like what happens to the monitoring task if you never cancel the token or dispose of the cancellation source, but that's a bit too deep.

In the code above we get a sort of a solution if we can control the code and we can actually cancel things gracefully inside of it. But what if I can't (or won't)? Can I get something that does what I wanted Task.Run to do: execute something and, when I cancel it, stop it from executing?

And the answer, using what we learned above, is yes, but as explained at the beginning, it may have effects like resource leaks. Here it is:
/// <summary>
/// Run an action and kill it when canceling the token
/// </summary>
/// <param name="action">The action to execute</param>
/// <param name="token">The token</param>
/// <param name="waitForGracefulTermination">If set, the task will be killed with delay so as to allow the action to end gracefully</param>
private static Task RunCancellable(Action action, CancellationToken token, TimeSpan? waitForGracefulTermination=null)
{
// we need a thread, because Tasks cannot be forcefully stopped
var thread = new Thread(new ThreadStart(action));
// we hold the reference to the task so we can check its state
Task task = null;
task = Task.Run(() =>
{
// task monitoring the token
Task.Run(() =>
{
// wait for the token to be canceled
token.WaitHandle.WaitOne();
// if we wanted graceful termination we wait
// in this case, action needs to know about the token as well and handle the cancellation itself
if (waitForGracefulTermination != null)
{
Thread.Sleep(waitForGracefulTermination.Value);
}
// if the task has not ended, we kill the thread
if (!task.IsCompleted)
{
thread.Abort();
}
});
// simply start the thread (and the action)
thread.Start();
// and wait for it to end so we return to the current thread
thread.Join();
// throw exception if the token was canceled
// this will not be reached unless the thread completes or is aborted
token.ThrowIfCancellationRequested();
}, token);
return task;
}

As you can see, the solution is to run the action on a thread and then manually kill the thread. This means that any control of where and how the action is executed is wrestled from the default TaskScheduler and given to you. Also, in order to force the stopping of the task, you use Thread.Abort, which may have nasty side effects. Here is what Microsoft says about it:



Bummer! .NET Core doesn't want you to kill threads. However, if you are really determined, there is a way :) Use ThreadEx.Abort(thread);


Bonus code: How do you get the cancellation token if you have the task?
var token = new TaskCanceledException(task).CancellationToken;
It might not help too much, especially if you want to use it inside the task itself, but it might help clean up the code.

Conclusion


Just like async/await, using the provided cancellation token method will only pollute your code with little effect. However, considering you want to use a common interface for the purpose, use RunCancellable instead of Task.Run and handle the token manually whenever you feel resources have been allocated and need to be cleaned up first.

and has 0 comments
If there is something that went wrong with this book, then it has to be the cover on Goodreads: a hipster young man with dark hair, a goatee and a pointlessly fancy dagger, which has almost no connection to the story. Instead, try the one on Amazon, which at least doesn't offend. And that concludes what went wrong with The Black Prism! I actually liked it a lot.

The story feels like so many other young adult fantasy novels, with the young child with important ancestry that had a bad childhood and is suddenly thrown in a world of magic, war and intrigue, but the characters are fresh, their motivations carefully crafted with respectful attention to detail. The world building follow suit, with a novel magic system, a deep history and not all yet revealed. The writing is good, too. After reading this first book in the Lightbringer saga, I immediately felt the need to read the next one in the series. But there is a dark side to all this, too, as The Black Prism isn't a stand alone book. If you like it, you will have to read it all.

Bottom line: I really liked the love Brent Weeks weaved in his book. This is not one of those "give me your money now" kind of work, it's something that has value and beauty. It's not the greatest book ever written, but what book is? For the fantasy genre, it was pretty entertaining (and big!).

and has 0 comments
When I was a child I was obsessed with dinosaurs. I was going through the pages of the Zoological Atlas again and again, looking at the big lizard like monsters and memorizing all of their names. If I would have had access to a book like Steve Brusatte's, I would have probably become a paleontologist! By that I mean that the book is good... for an eight year old or for somebody who is already giddy with the prospect of reading about their favorite subject. Now, decades later, I really made an effort to enjoy The Rise and Fall of the Dinosaurs, but it had no wow factor anymore. The plethora of names that I haven't known about when I was smaller than a toddler did not bring me joy. Hearing about feathered dinosaurs and what is the most likely reason feathers evolved at all or how they dinosaurs turned into their modern day form - the birds, even the tales about the dwarf dinosaurs found in my own homeland merely made the book bearable. Having a long chapter focused on Tyrannosaurs and having my book reader stop after each T. in T. Rex didn't help either.

My verdict, therefore, is that it is a good history book. It is well written and the passion of the author is palpable and admirable. Yet, unless you either know nothing about dinosaurs or you already love them, you won't read anything really amazing or new. It is, quite literally, a history of how dinosaurs rose and fell and it feels like reading a history book. Somehow, I was expecting more, something that explored in depth a lost world, but in fact it only made clear how little we know and how tiny chances are that this will ever change. Instead of the feel of a lush green world where danger loomed and beauty abounded, I got a dry dusty look at people digging in rocks for small hints of that world. It was like looking at shadows and trying to figure out what made them.

and has 0 comments

Have you ever found a book so bland that you just refused to continue reading it? To me it happens rarely, but it did with Malice, by John Gwynne. And I do feel a sense of loss, since the reviews I've seen are all so overwhelmingly positive. Maybe if I would have just read a few more formulaic chapters I would have gotten to the part when something, anything, happens.

But no, I do have a lot of books to read and I am not going to waste my time reading about another child who wants to be a hero, but he's weak and bullied, another large blacksmith who was once a soldier, another pair of good and evil gods and their minions, noble savages, strong princesses, evil viziers and so on and so on. After several chapters all I got was a bunch of people in different contexts, each with their own names, friends, family, dreams, history and narration. Whenever I thought something would happen, another character with a silly name came along to perform whatever ritual is assigned to its cardboard role. Confusing and boring as hell.

Bottom line, I couldn't even begin to finish it. I probably read about 10-15% and gave up.

and has 0 comments
Much like City of Stairs, Foundryside is a steampunk story set in a world where power resides in the hands of a few "houses" who use a magical programming language to alter reality. The lead character is also a girl, the plot also revolves around someone who wants to abuse ancient magic to rule the world and the state of knowledge is yet again recovering from a major catastrophe that veiled the past. Yet with all this, I liked the book less.

Just as the story moved from a more mystical setting to a more rational, scientific one, so did Robert Jackson Bennett's writing turned more formulaic. It's like he took something he had success with and applied the same exact formula, with some improvements related to what people want to read. As a result, the characters are less mysterious and more cardboard, the hints peppered around the story for the reader to glimpse where it is going are way too revealing (something that bothered me a little in City of Stairs, too, but here it was just too obvious). But what bothered me most was that the characterization: some were way too modern, way too educated or philosophical, considering their background, and the divide between good and evil was so obvious, back to the annoying cliché where the good characters are principled and loyal and intelligent and their opponents are insane, frustrated and ugly.

Bottom like, I liked the book, but I feel like Foundryside is a step back for Bennett. It was harder to empathize with the heroes and almost impossible to do so with the antagonists. The story felt recycled from a basic idea scrived with the same recipe as City of Stairs, but more lazily.

and has 0 comments
This should be a simple question with a simple answer, but if you google for Angular Material tooltip styling or length or width you get different answers that are not always complete or even correct. The problem: you have something like <a matTooltip="some message" matTooltipClass="myTooltipClass" ... as per the examples easy to find. However, it doesn't seem to be working. The styling for myTooltipClass does not apply. Here are some points to check off while searching for the problem:
  1. Check whether myTooltipClass is defined in the component or the global CSS file. It should either be in the global CSS file (so it applies to everything) or your component should declare encapsulation: ViewEncapsulation.None
  2. Check the declaration of the class is specific enough. DO NOT use !important to fix this, although it would work. Try something like this: mat-tooltip-component .mat-tooltip.myTooltipClass {...}

To see if the class is applied, set the background-color property to red or something. If the class applies, you managed to define it correctly. If it applies partially, it's not specific enough. To change the width, use max-width. To make the tooltip wrap use white-space: wrap; and word-wrap: break-word;

As a reference, this is how the HTML looks for a rendered tooltip:
<div class="cdk-overlay-container">
<div class="cdk-overlay-connected-position-bounding-box" dir="ltr" style="top: 0px; left: 0px; height: 100%; width: 100%;">
<div id="cdk-overlay-1" class="cdk-overlay-pane mat-tooltip-panel" style="pointer-events: auto; top: 8px; left: 417.625px;">
<mat-tooltip-component aria-hidden="true" class="ng-tns-c34-15 ng-star-inserted" style="zoom: 1;">
<div class="mat-tooltip ng-trigger ng-trigger-state" style="transform-origin: left center; transform: scale(1);">Info about the action</div>
</mat-tooltip-component>
</div>
</div>
</div>

and has 0 comments
What makes a good story? It has to be the telling or writing style, of course, but then there are other factors: believable and sympathetic characters, an interesting idea, a tight plot, good world building, entertaining scenes. I am happy to report that City of Stairs aced everything! I haven't heard of Robert Jackson Bennett before, but I am sure to remember his name now. The first book in a trilogy, City of Stairs wasn't just blessingly self contained, but also made me happy to have following books to continue the story.

The main character is a woman who does everything from conviction, care for others and most of all her own intelligence and effort, not because of her gender. The story is a detective story, set in a fictional preindustrial almost steampunk world where gods recently existed until people killed them. It is a book of mystery, intrigue, politics, detective like investigations, spirituality and magic, but held tight around a solid core of whodunit and great character and world building. It reminded me of the wonder I felt when starting reading Brandon Sanderson's books.

Bottom line: not the greatest work of literary fiction that ever existed, but I couldn't find any fault with it. Per my definition, it was a perfect book.

and has 0 comments

At first I thought this will rehash the same information I've got from books I've read recently: how microorganisms are everywhere and how they live in symbiosis and cooperation with themselves, plants and animals, how the imbalance in the ecosystem is what we normally get to call disease, maybe some epidemics stories and so on. Instead I've got an ode to E. Coli and how studying it for decades has revealed to us in details the way life works. It's Carl Zimmer's multifaceted portrait of a single species of bacteria (although that's a lot of bacteria, if you get to read the book).

Well written even if more technical than the average popular science book, Microcosm explains how heredity works, DNA, RNA, proteins, amino acids, bacteria, biofilms, archaea, eukaryotes, viruses, plasmids, mutations, evolution, resistance and so on until it gets to creationists, genetic engineering and exobiology, all while following our scientific history built on the study of this one bacteria, the workhorse of microbiology. In fact, it is so focused on E. Coli, that it snubs most other bacteria, it talks little of epidemics or the microbe ecosystem and instead focuses on how things work. It's like an engineer's view on how life works, or a user's manual for Escherichia coli.

I liked the book and I will probably read more from the same author. I mean, if he writes a book per microbe species I could read his books until one of us dies :) I highly recommend it not only for its subject, but also for how it makes clear the inner workings of life and evolution. I would have loved to read this book when I was 12.

and has 0 comments
To be honest, I've reached the beginning of the third book in The Faded Sun Omnibus and I've decided to stop.

It was 1978. Religious people living in the desert under strict rules and brandishing swords were still cool and not considered terrorists. C.J.Cherryh decides to write a story about a fierce warrior race that works in the employ of others to wage space war, driven by a very exact culture that emerged in the desert. They carry black veils that only let show their eyes and are very partial to rituals and hand to hand combat. No wonder humans kicked their asses, but even they are terribly anachronistic. They have waged 40 years of war with the humans, under the contract of the Regul, fat immobile and amoral beings that care only for their own tribe's well being.

Reminds you of Dune, the Freemen and the Harkonen? Well, this is where the similarity ends. Where Dune was deep, these three books are tediously drudging through all kinds of futile rituals and each character is painfully introspective, to the point that tough warriors bred for battle are recognizing and thinking about their feelings of fear all the time. Worse, nothing really seems to be happening. It takes a book for a ship to get to its destination.

And the book has aged poorly, even when in the whole thing there are maybe a page of technical descriptions, probably less. There is no mention on what makes the ships run, what types of weapons are used, how computers work, etc. A ship just "fires" and it is never even described in what way.

But the ultimate sin is how little sense it makes. I mean, this is the age of Star Wars, where... errr... people on starships wage battles with swords... OK, the author isn't the only one who screwed stories up, but the Mri are presented as this scourge of the battles, yet they don't know technology or can even read or write, they are appalled by mass warfare and prefer hand to hand combat (like real men!) and are strict in what they are allowed to do, know or even think. It's like giving space weaponry to the Flinstones. OK, you get the Jetsons, but how is that supposed to be terrifying or a match to the voracious human penchant for mass destruction? And there is more. After 40 years, we learn that people have never captured Mri alive, never studied them. The Mris themselves are accompanied by huge bear like semitelepathic animals that they never name or even know how they reproduce. Unlike Frank Herbert, who was obsessed with ecology, Cherryh feels no need to explain how a species of huge carnivores exists on harsh desert planets that are almost devoid of life and water or how three completely different species can share air and food, or how the animals and plants on a different planet are the same as from one that lay 120 planets away, or how language and culture stays the same for 80000 years. A lot of things just don't make sense, including the story's main premise, which is the fear that humans and Regul alike carry for the Mri.

Bottom line: if it were nice to read at least, I would have given it a shot, but after two books of people thinking in fear about what others are thinking of them, I gave it up. It was just tediously boring.

Now, Cherryh was at the beginning of her illustrious career and there are books written by her that I liked. I just hated this one.

and has 0 comments
The City in the Middle of the Night reminded me of Octavia Butler's Xenogenesis, only way lighter. The same female centric focus, the slight weirdness of descriptions and feelings that comes from a truly different perspective. Charlie Jane Anders describes a planet far away from Earth, a colony that devolved after humans reached the planet until it got to feudal levels of government and technology. The planet is tidally locked, so people live on the narrow edge that separates frigid night and scorching day. There are some aliens there as well. Pretty cool story and concept, so much so that I hated it when the book ended and it was NOT a trilogy or a saga or whatever. Hard to please me, right?

The writing style isn't on par with the richness of the concepts, though, and I was also thrown off often by gaps in the understanding of science, social norms and even sensory descriptions. Yet once I understood the author is a transgender woman with sensory integration disorder, it started to make sense. The main characters are all women. There are no real romantic or familial relationships between them, unless counting the fact that they are always feeling things strongly and lying together in beds without doing anything. The lack of sexuality in the novel is refreshing but going a long way in the other direction until it feels eerie. And they often react physically or mentally in such overblown ways that it's hard to empathize. Stuff like someone saying something and they suddenly go to a corner to heave, or having seen someone smile or being touched in a certain way just short circuits their brain. There are a lot of leftover threads in the book, things that get partially described and you just wait for them to be explained later on and they just don't. Also the mix of first person perspective for Sophie and third person for everybody else is strange and forces one of the characters as the main one, even if maybe a reader would relate better with somebody else.

So I had difficulty in rating this book. I would give an excellent rating to the world building and the concepts presented there, but an average on characterization (even if most of the book is about what characters do and think and feel). I would rate some descriptions of internal struggle and emotion as great, but others really lame, especially when it comes to characters who seem to be designed to be thrown away later on. The writing style is not bad, but not great either. It's a mixture of brilliance and average that is hard to reconcile into a single metric. I mean, I could describe the entire plot of the book in two paragraphs; the rest is just people bumbling around trying to make sense of the world and themselves. No character has a real back story, except a few defining moments that feel pulled out of a hat, and they are understandably confused all the time. Who are their parents? Everybody in the book is an orphan. Why so many descriptions of invented food if does nothing for the plot, yet no sex, only a rare and weird longing sort of platonic love? Why is everybody so casually violent, yet so disgusted with violence in their inner thoughts?

It seems to me that this is a book that only some will be able to connect to (the others will get delirious and murderous). I liked the ideas, I liked the characters, it's just that they are coming from nowhere and ultimately going nowhere.

and has 0 comments
The book might put you off at the beginning, as it starts with a no bullshit nomenclature chapter. It basically says: "This is how I am going to call things in this book and if you don't like it, talk to people who actually care about semantics". The rest of the book continues with the same directness and I believe it is one of the works' best qualities.

Good Germs, Bad Germs starts like a few other books on the subject I've read recently, with a short history of how people have looked upon disease and its causes: Hippocrates' humors, the (all bad) germ theory, vaccines, antibiotics, the bad antibiotics and the good germs, modern understanding of immunity. And yet this is just the first half of the story. The rest is about new ideas, actual therapies and studies, real life cases and attempts to bring this new knowledge into the public domain.

I really liked the book. It's easy to read, easy to understand. Less of the story-like or anecdotal writing style of some other works and more to the point. I also liked that it doesn't take sides: one therapy has to go through wholly unreasonable FDA hoops to be allowed to even be tested in humans, the author points both positive and negative aspects of being prudent. Is it ridiculous that the lack of communication between American hospitals hides invisible epidemics that then get reported by Canada or Europe and end back into the States' headlines as foreign diseases? Jessica Snyder Sachs just reports on the facts, letting the reader draw their own conclusions.

Bottom line: I thought it would be just a repeat of the same information I've become familiar with lately, yet it was not only a different way of tackling the same subject, but also a lot more information about actual attempts to use it in real situations. I recommend it to anyone trying to understand how we stand in this coevolution with the microbes living inside and outside us.

and has 0 comments
Knights of the Borrowed Dark is a typical fantasy story filled with tropes like: "the one", "son of..." (or "noble family" or "everybody is related to everybody"), "secret war (for no good reason)", "light versus dark", "evil must be fought with swords", "no one tells you anything, even if it makes no sense", "dark king" and so on. The main character is a Mary Sue, an orphan who doesn't know his parents and has lived his entire life in an orphanage, but somehow is a balanced, well read individual who favors rationality to emotion, yet has no problem using both. Add the trope of trilogy to this and you have a complete picture.

Now, does that mean I was not entertained? Nope. It was all fun and games and I've finished the book in a day, yet I can't but be disappointed in both the formulaic nature of the story and the fact that I liked it anyway. The bottom line is that Dave Rudden writes decently and has enough skill and humor to make the same story you've read or seen a dozen times already feel pleasant. So read it, if you like that kind of thing, but don't expect anything above ordinary.