Tuesday 29 March 2016

The Magicians book trilogy, by Lev Grossman

Trilogy boxed set I will be reviewing all three books in The Magicians trilogy, by Lev Grossman, as they are one complete story with a beginning and an end, as well as an overarching moral. My review of the first book only, from the perspective of someone who enjoys the (very different!!) TV show, stands.

To understand The Magicians you need to understand who Lev Grossman is: a book critic for Time magazine. As such, he must have had a very strange experience trying to write after probably demolishing a lot of other writers for their lack of skill or overuse of tropes. Therefore some sort of alarm bells must sound when he undertakes to writing a "trilogy of fantasy books", a concept that is a meta-trope in itself. I believe he attempted to break the mould of the genre by using flawed every day characters on a journey that is less heroic as closer to real life: random things happening to you, bad things which you can't avoid, defeat or change, even if you try, which sometimes you don't, because you are scared or bored or selfish. At the end of said journey you are altered, but is it a better you, or just an old damaged version of the dreamer kid you started out as?

For this belief alone, I say that the books were decent because they achieved their purpose. The topics approached are more adult, the characters different from the plethora of fantasy heroes, the elements that seem to randomly appear get resolved somewhere in the far future rather than in the confined timeframe of an "episode". I loved the concept and therefore I liked the books.

However, that doesn't mean everything is rosy in Fillory. The characters are barely built up, the reader starves for some understanding of why people do the things they do or even think or feel in a certain way. Important influences such as home, childhood, parents, siblings, good friends are being ignored and abandoned, while the action of the people in the books are more often described than explained. Satirical references to well known works in the fantasy and science fiction genres pepper the books, but those stories at least attempted some consistency, while The Magicians, especially the Fillory part, feels like an LSD trip of an autistic dork.

The worst sin the books commit, and that is in direct conflict with what I think their goal was, is to make the characters almost impossible to empathize with. All of them move through the story like pieces on a board, almost indifferent to their surroundings and the people that accompany them and mostly annoyed. Whatever deep feelings they do have come out as quirky and obsessive, rather than real. It was with great dissatisfaction that I realized that the character I most identified with and believed real was The Beast, which is a terrible villain for most of the first half of the story. People died, were hurt, tortured and violated, resurrected and I couldn't care less. Mythological monsters and weird random creations were epically battling at the end of the world, and I was just bored, waiting for something interesting to happen.

Bottom line: good idea, bad implementation. Interesting to read, but hardly something that I would recommend as good writing.

Wednesday 23 March 2016

Chrome extension: Bookmark Explorer

Update 29 August 2017 - Version 3.0.4: The extension has been rewritten in EcmaScript6 and tested on Chrome, Firefox and Opera.

Update 03 March 2017 - Version 2.9.3: added a function to remove marketing URLs from all created bookmarks. Enable it in the Advanced settings section. Please let me know of any particular parameters you need purged. So far it removes utm_*, wkey, wemail, _hsenc, _hsmi and hsCtaTracking.

Update 26 February 2017: Version (2.9.1): added customizing the URL comparison function. People can choose what makes pages different in general or for specific URL patterns
Update 13 June 2016: Stable version (2.5.0): added Settings page, Read Later functionality, undelete bookmarks page and much more.
Update 8 May 2016: Rewritten the extension from scratch, with unit testing.
Update 28 March 2016: The entire source code of the extension is now open sourced at GitHub.

a screenshot of the extensions Whenever I read my news, I open a bookmark folder containing my favorite news sites, Twitter, Facebook, etc. I then proceed to open new tabs for each link I find interesting, closing the originating links when I am done. Usually I get a number of 30-60 open tabs. This wreaks havoc on my memory and computer responsiveness. And it's really stupid, because I only need to read them one by one. In the end I've decided to fight my laziness and create my first browser extension to help me out.

The extension is published here: Siderite's Bookmark Explorer and what it does is check if the current page is found in any bookmark folder, then allow you to go forward or backwards inside that folder.

So this is my scenario on using it:
  1. Open the sites that you want to get the links from.
  2. Open new tabs for the articles you want to read or YouTube videos you want to watch,etc.
  3. Bookmark all tabs into a folder.
  4. Close all the tabs.
  5. Navigate to the bookmark folder and open the first link.
  6. Read the link, then press the Bookmark Navigator button and then the right arrow. (now added support for context menu and keyboard shortcuts)
  7. If you went too far by mistake, press the left arrow to go back.

OK, let's talk about how I did it. In order to create your own Chrome browser extension you need to follow these steps:

1. Create the folder


Create a folder and put inside a file called manifest.json. It's possible structure is pretty complex, but let's start with what I used:
{
"manifest_version" : 2,

"name" : "Siderite's Bookmark Explorer",
"description" : "Gives you a nice Next button to go to the next bookmark in the folder",
"version" : "1.0.2",

"permissions" : [
"tabs",
"activeTab",
"bookmarks",
"contextMenus"
],
"browser_action" : {
"default_icon" : "icon.png",
"default_popup" : "popup.html"
},
"background" : {
"scripts" : ["background.js"],
"persistent" : false
},
"commands" : {
"prevBookmark" : {
"suggested_key" : {
"default" : "Ctrl+Shift+K"
},
"description" : "Navigate to previous bookmark in the folder"
},
"nextBookmark" : {
"suggested_key" : {
"default" : "Ctrl+Shift+L"
},
"description" : "Navigate to next bookmark in the folder"
}
}
}

The manifest version must be 2. You need a name, a description and a version number. Start with something small, like 0.0.1, as you will want to increase the value as you make changes. The other thing is that mandatory is the permissions object, which tells the browser what Chrome APIs you intend to use. I've set there activeTab, because I want to know what the active tab is and what is its URL, tabs, because I might want to get the tab by id and then I don't get info like URL if I didn't specify this permission, bookmarks, because I want to access the bookmarks, and contextMenus, because I want to add items in the page context menu. More on permissions here.

Now, we need to know what the extension should behave like.

If you want to click on it and get a popup that does stuff, you need to specify the browser_action object, where you specify the icon that you want to have in the Chrome extensions bar and/or the popup page that you want to open. If you don't specify this, you get a default button that does nothing on click and presents the standard context menu on right click. You may only specify the icon, though. More on browserAction here.

If you want to have an extension that reacts to background events, monitors URL changes on the current page, responds to commands, then you need a background page. Here I specify that the page is a javascript, but you can add HTML and CSS and other stuff as well. More on background here.

Obviously, the files mentioned in the manifest must be created in the same folder.

The last item in the manifest is the commands object. For each command you need to define the id, the keyboard shortcut (only the 0..9 and A..Z are usable unfortunately) and a description. In order to respond to commands you need a background page as shown above.

2. Test the extension


Next you open a Chrome tab and go to chrome://extensions, click on the 'Developer mode' checkbox if it is not checked already and you get a Load unpacked extension button. Click it and point the following dialog to your folder and test that everything works OK.

3. Publish your extension


In order to publish your extension you need to have a Chrome Web Store account. Go to Chrome Web Store Developer Dashboard and create one. You will need to pay a one time 5$ fee to open it. I know, it kind of sucks, but I paid it and was done with it.

Next, you need to Add New Item, where you will be asked for a packed extension, which is nothing but the ZIP archive of all the files in your folder.

That's it.

Let's now discuss actual implementation details.

Adding functionality to popup elements


Getting the popup page elements is easy with vanilla Javascript, because we know we are building for only one browser: Chrome! So getting elements is done via document.getElementById(id), for example, and adding functionality is done via elem.addEventListener(event,handler,false);

One can use the elements as objects directly to set values that are related to those elements. For example my prev/next button functionality takes the URL from the button itself and changes the location of the current tab to that value. Code executed when the popup opens sets the 'url' property on the button object.

Just remember to do it when the popup has finished loading (with document.addEventListener('DOMContentLoaded', function () { /*here*/ }); )

Getting the currently active tab


All the Chrome APIs are asynchronous, so the code is:
chrome.tabs.query({
'active' : true,
'lastFocusedWindow' : true
}, function (tabs) {
var tab = tabs[0];
if (!tab) return;
// do something with tab
});

More on chrome.tabs here.

Changing the URL of a tab


chrome.tabs.update(tab.id, {
url : url
});

Changing the icon in the Chrome extensions bar


if (chrome.browserAction) chrome.browserAction.setIcon({
path : {
'19' : 'anotherIcon.png'
},
tabId : tab.id
});

The icons are 19x19 PNG files. browserAction may not be available, if not declared in the manifest.

Get bookmarks


Remember you need the bookmarks permission in order for this to work.
chrome.bookmarks.getTree(function (tree) {
//do something with bookmarks
});

The tree is an array of items that have title and url or children. The first tree array item is the Bookmarks Bar, for example. More about bookmarks here.

Hooking to Chrome events


chrome.tabs.onUpdated.addListener(refresh);
chrome.tabs.onCreated.addListener(refresh);
chrome.tabs.onActivated.addListener(refresh);
chrome.tabs.onActiveChanged.addListener(refresh);
chrome.contextMenus.onClicked.addListener(function (info, tab) {
navigate(info.menuItemId, tab);
});
chrome.commands.onCommand.addListener(function (command) {
navigate(command, null);
});

In order to get extended info on the tab object received by tabs events, you need the tabs permission. For access to the contextMenus object you need the contextMenus permission.

Warning: if you install your extension from the store and you disable it so you can test your unpacked extension, you will notice that keyboard commands do not work. Seems to be a bug in Chrome. The solution is to remove your extension completely so that the other version can hook into the keyboard shortcuts.

Creating, detecting and removing menu items


To create a menu item is very simple:
chrome.contextMenus.create({
"id" : "menuItemId",
"title" : "Menu item description",
"contexts" : ["page"] //where the menuItem will be available
});
However, there is no way to 'get' a menu item and if you try to blindly remove a menu item with .remove(id) it will throw an exception. My solution was to use an object to store when I created and when I destroyed the menu items so I can safely call .remove().

To hook to the context menu events, use chrome.contextMenus.onClicked.addListener(function (info, tab) { }); where info contains the menuItemId property that is the same as the id used when creating the item.

Again, to access the context menu API, you need the contextMenus permission. More about context menus here.

Commands


You use commands basically to define keyboard shortcuts. You define them in your manifest and then you hook to the event with chrome.commands.onCommand.addListener(function (command) { });, where command is a string containing the key of the command.

Only modifiers, letters and digits can be used. Amazingly, you don't need permissions for using this API, but since commands are defined in the manifest, it would be superfluous, I guess.

That's it for what I wanted to discuss here. Any questions, bug reports, feature requests... use the comments in the post.

Tuesday 22 March 2016

Monday 21 March 2016

The Magicians, by Lev Grossman

Book cover I'm seeing a pattern here already. After The Expanse, which surprised me with how good the TV show was compared to the books, now The Magicians does the same. There is something to be said about hindsight and when you are adapting a series of books for the small screen you get a lot of resources that the writer himself did not have when he began. I have a feeling that many things that happened in the first season of the TV series will not even happen in the second book. The plot has been changed as well, quite a lot, to the point that now I will be reviewing a book that has at most half of it to do with what you might have seen on TV and another half that you probably won't see even in the future.

In The Magicians, the first book in the series with the same name, Lev Grossman describes a pretty dorky character suddenly finding that magic is real and he is a magician. But while it starts like the typical fantasy story, it continues quite differently, with a school of magic that doesn't seem to care about its students much, a way of learning and doing magic that is never quite explained, but described as tedious and difficult, and an overall depressing view on the world. The main character isn't even very heroic, quite the opposite, he really does think and feel like a 'dork'. If anything, he is a coward and a person who's few feelings are confused and pretty much self involved. His friends are none the better and the entire thing soon started to take a toll on me, who failed to empathize with anything and anybody.

Another issue with the book is that it is rarely consistent. Things happen without much explanation and then they turn into others. Modern culture references mix with awe of magic and then seriously fucked up shit, only to slip into irony or even slapstick comedy. It gets the reader curious about what is going to happen next, but always on the brink of "why am I reading this?". Myself I am sometimes completely engrossed in a bit of the story only to see it end abruptly and leading to nowhere. Doors to other realms are opened and nobody really cares for it for any reason other than to become kings and party all the time. People die or characters do some really shitty things, but the others are all calm and going on with their lives.

So yeah, I don't know if I should recommend the books yet. The show is levels of magnitude better so far, in story, consistency and character development. Even if I could buy into the whole borderline autistic asshole of a main character, which I was ready to, the sudden and often context switch made me really difficult for me to enjoy the series so far. However it is original and I have not read a book that sees the world quite in the same way. If you are tired of the same old fantasy stuff, The Magicians is a bit more adult and hard to put in a clear box, touching real young people topics, like sexuality, alcohol, drugs, depression, uncertainty, the search for happiness.

Friday 18 March 2016

How to draw outlined text in WPF and then how to draw anything at all on that text

I have found a new addiction: prowling StackOverflow and answering questions. It does teach a lot, because you must provide in record time a quality answer that is also appreciated by the person asking the question and by the evil reviewers who hunt you down and downvote you if you mess up. OK, they're not evil, they're necessary. Assholes! :) Anyway, in honor of my 1000th point, I want to share with you the code that I have been working on for one of the questions.

resulting text The question had a misleading title: How to inherit a textblock properties to a custom control in c# and had a 500 points reward on it (that's a lot) placed there by another person than the original requester. In fact, the question was more about how to use a normal TextBlock control, but also have it display outlined text, with a specific "stroke" and thickness. Funny thing, I had already answered this question a few days before. The bounty, though, was set on a more formal answer, one that would cover any graphical transformation on a TextBlock, considering that the control had sealed the OnRender overload and there was no way of reaching its drawing context.

We need to consider that WPF was designed to be modular, unlike ASP.Net or Windows Forms, for which inheritance was the preferred way to go. Instead WPF favors composition. That is why controls are sealing their OnRender implementation, because there is another way of getting to the drawing context and that is an Adorner. Now, it is also possible to use an Effect, but for the life of me I couldn't understand how to easily write one.

Anyway, adorners have their pros and cons. The pro is that you get to still use a TextBlock or whatever control you want to use and you just adorn it with what you need. It receives a UIElement in the constructor and in its OnRender method you get access to the drawing context of the control. Here is the code of the adorner that I presented in the StackOverflow question:
public class StrokeAdorner : Adorner
{
private TextBlock _textBlock;

private Brush _stroke;
private ushort _strokeThickness;

public Brush Stroke
{
get
{
return _stroke;
}

set
{
_stroke = value;
_textBlock.InvalidateVisual();
InvalidateVisual();
}
}

public ushort StrokeThickness
{
get
{
return _strokeThickness;
}

set
{
_strokeThickness = value;
_textBlock.InvalidateVisual();
InvalidateVisual();
}
}

public StrokeAdorner(UIElement adornedElement) : base(adornedElement)
{
_textBlock = adornedElement as TextBlock;
ensureTextBlock();
foreach (var property in TypeDescriptor.GetProperties(_textBlock).OfType<PropertyDescriptor>())
{
var dp = DependencyPropertyDescriptor.FromProperty(property);
if (dp == null) continue;
var metadata = dp.Metadata as FrameworkPropertyMetadata;
if (metadata == null) continue;
if (!metadata.AffectsRender) continue;
dp.AddValueChanged(_textBlock, (s, e) => this.InvalidateVisual());
}
}

private void ensureTextBlock()
{
if (_textBlock == null) throw new Exception("This adorner works on TextBlocks only");
}

protected override void OnRender(DrawingContext drawingContext)
{
ensureTextBlock();
base.OnRender(drawingContext);
var formattedText = new FormattedText(
_textBlock.Text,
CultureInfo.CurrentUICulture,
_textBlock.FlowDirection,
new Typeface(_textBlock.FontFamily, _textBlock.FontStyle, _textBlock.FontWeight, _textBlock.FontStretch),
_textBlock.FontSize,
Brushes.Black // This brush does not matter since we use the geometry of the text.
);

formattedText.TextAlignment = _textBlock.TextAlignment;
formattedText.Trimming = _textBlock.TextTrimming;
formattedText.LineHeight = _textBlock.LineHeight;
formattedText.MaxTextWidth = _textBlock.ActualWidth - _textBlock.Padding.Left - _textBlock.Padding.Right;
formattedText.MaxTextHeight = _textBlock.ActualHeight - _textBlock.Padding.Top;// - _textBlock.Padding.Bottom;
while (formattedText.Extent==double.NegativeInfinity)
{
formattedText.MaxTextHeight++;
}

// Build the geometry object that represents the text.
var _textGeometry = formattedText.BuildGeometry(new Point(_textBlock.Padding.Left, _textBlock.Padding.Top));
var textPen = new Pen(Stroke, StrokeThickness);
drawingContext.DrawGeometry(Brushes.Transparent, textPen, _textGeometry);
}

}

The first con is that you need to use it in code, there is no native way of using it from XAML. The second con, and the most brutal, is that when the control changes what it renders, the adorner doesn't follow suit! Someone answered it better than I can describe it here. Guess where? On StackOverflow, of course.

The first problem I have solved with another great WPF contraption: attached properties. Here is the code for the properties:
public static class Adorning
{
public static Brush GetStroke(DependencyObject obj)
{
return (Brush)obj.GetValue(StrokeProperty);
}
public static void SetStroke(DependencyObject obj, Brush value)
{
obj.SetValue(StrokeProperty, value);
}
// Using a DependencyProperty as the backing store for Stroke. This enables animation, styling, binding, etc...
public static readonly DependencyProperty StrokeProperty =
DependencyProperty.RegisterAttached("Stroke", typeof(Brush), typeof(Adorning), new PropertyMetadata(Brushes.Transparent, strokeChanged));

private static void strokeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var stroke= e.NewValue as Brush;
ensureAdorner(d,a=>a.Stroke=stroke);
}

private static void ensureAdorner(DependencyObject d, Action<StrokeAdorner> action)
{
var tb = d as TextBlock;
if (tb == null) throw new Exception("StrokeAdorner only works on TextBlocks");
EventHandler f = null;
f = new EventHandler((o, e) =>
{
var adornerLayer = AdornerLayer.GetAdornerLayer(tb);
if (adornerLayer == null) throw new Exception("AdornerLayer should not be empty");
var adorners = adornerLayer.GetAdorners(tb);
var adorner = adorners == null ? null : adorners.OfType<StrokeAdorner>().FirstOrDefault();
if (adorner == null)
{
adorner = new StrokeAdorner(tb);
adornerLayer.Add(adorner);
}
tb.LayoutUpdated -= f;
action(adorner);
});
tb.LayoutUpdated += f;
}

public static double GetStrokeThickness(DependencyObject obj)
{
return (double)obj.GetValue(StrokeThicknessProperty);
}
public static void SetStrokeThickness(DependencyObject obj, double value)
{
obj.SetValue(StrokeThicknessProperty, value);
}
// Using a DependencyProperty as the backing store for StrokeThickness. This enables animation, styling, binding, etc...
public static readonly DependencyProperty StrokeThicknessProperty =
DependencyProperty.RegisterAttached("StrokeThickness", typeof(double), typeof(Adorning), new PropertyMetadata(0.0, strokeThicknessChanged));

private static void strokeThicknessChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ensureAdorner(d, a =>
{
if (DependencyProperty.UnsetValue.Equals(e.NewValue)) return;
a.StrokeThickness = (ushort)(double)e.NewValue;
});
}
}
and an example of use:
<TextBlock
x:Name="t1"
HorizontalAlignment="Stretch"
FontSize="40"
FontWeight="Bold"
local:Adorning.Stroke="Red"
local:Adorning.StrokeThickness="2"
Text="Some text that needs to be outlined"
TextAlignment="Center"
TextWrapping="Wrap"

Width="600">
<TextBlock.Foreground>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Offset="0" Color="Green" />
<GradientStop Offset="1" Color="Blue" />
</LinearGradientBrush>
</TextBlock.Foreground>
</TextBlock>

Now for the second problem, the StrokeAdorner already has a fix in the code, but I need to be more specific about it, because as it is written now I believe it leaks memory. Nothing terribly serious, but still. The code I am talking about is in the constructor:
foreach (var property in TypeDescriptor.GetProperties(_textBlock).OfType<PropertyDescriptor>())
{
var dp = DependencyPropertyDescriptor.FromProperty(property);
if (dp == null) continue;
var metadata = dp.Metadata as FrameworkPropertyMetadata;
if (metadata == null) continue;
if (!metadata.AffectsRender) continue;
dp.AddValueChanged(_textBlock, (s, e) => this.InvalidateVisual());
}
Here I am enumerating each property of the target (the TextBlock) and checking if they are dependency properties and if they have in their metadata the AffectsRender flag, they I add a property change handler which calls InvalidateVisual on the adorner. Notice that in no part of the code do I remove those handlers. However, at this time I don't think it is a problem. Anyway, the code itself is more about the principles of the thing, rather than the implementation.

If I were to talk about the implementation, I would say that this code doesn't always work. Even if I use the padding of the element and its actual dimensions, the FormattedText sometimes renders things differently from the TextBlock, especially if one plays with TextWrap and TextTrimming. But that is another subject altogether. Yay! 1000 points on StackOverflow! "And what do you do with the points?" [my wife :(]

Monday 14 March 2016

Creating a C# construct that acts like a more complex switch/case

Inspired by my own post about simulating F# active patterns in C# and remembering an old crazy post about using try/catch to emulate a switch on types, I came up with this utility class that acts and looks like a switch statement, but can do a lot more. The basic idea was to use a fluent interface to get the same functionality of switch, but also add the possibility of using complex objects as case values or even code conditions.
an example of use

First, here is the source code:
namespace Constructs
{
public static class Do
{
public static Switch<T> Switch<T>(T value)
{
return Constructs.Switch<T>.From(value);
}
}

public class Switch<T>
{
private bool _isDone;
private T _value;
private Type _valueType;

private Switch(T value)
{
this._value = value;
}

public static Switch<T> From(T value)
{
return new Switch<T>(value);
}

public Switch<T> Case(Func<T> valueFunc, Action<T> action, bool fallThrough = false)
{
if (_isDone) return this;
return Case(valueFunc(), action, fallThrough);
}

public Switch<T> Case(T value, Action<T> action, bool fallThrough = false)
{
if (_isDone) return this;
return If(v => object.Equals(value, v), action, fallThrough);
}

public void Default(Action<T> action)
{
if (_isDone) return;
action(_value);
}

public Switch<T> If(Func<T, bool> boolFunc, Action<T> action, bool fallThrough = false)
{
if (_isDone) return this;

if (boolFunc(_value))
{
action(_value);
_isDone = !fallThrough;
}

return this;
}

private Type getValueType()
{
if (_valueType != null) return _valueType;
if (object.Equals(_value, null)) return null;
_valueType = _value.GetType();
return _valueType;
}

public Switch<T> OfStrictType<TType>(Action<T> action, bool fallThrough = false)
{
if (_isDone) return this;
if (getValueType() == typeof(TType))
{
action(_value);
_isDone = !fallThrough;
}
return this;
}

public Switch<T> OfType<TType>(Action<T> action, bool fallThrough = false)
{
if (_isDone) return this;
if (getValueType() == null) return this;
if (typeof(TType).IsAssignableFrom(getValueType()))
{
action(_value);
_isDone = !fallThrough;
}
return this;
}
}
}
I use the static class Do to very easily get a Switch<T> object based on a value, then run actions on that value. The Switch class has a _value field and an _isDone field. When _isDone is set to true, no action is further executed (like breaking from a switch block). The class has the methods Case, and If, as well as OfType and OfStrictType, all of which execute an action if either the value, the function, the condition or the type provided match the initial value. Default is always last, executing an action and setting _isDone to true;

Here is an example of use:
for (var i = 0; i < 25; i++)
{
Do.Switch(i)
.Case(10, v => Console.WriteLine("i is ten"), true)
.Case(() => DateTime.Now.Minute / 2, v =>
Console.WriteLine($"i is the same with half of the minute of the time ({v})"), true)
.If(v => v % 7 == 0, v => Console.WriteLine($"{v} divisible by 7"))
.Default(v => Console.WriteLine($"{v}"));
}
where the numbers from 0 to 25 are compared with 10, the half of the minutes value of the current time and checked if they are divisible by 7, else they are simply displayed. Note that the first two Case methods receive an optional bool parameter that allows the check to fall through, so that the value is checked if it is equal to 10, but also if it is twice the minute value or divisible by 7. On the other hand, if the value is divisible by 7 it will not display the value in the Default method.

Here is an example that solves the type check with the same construct:
var f = new Action<object>(x =>
Do.Switch(x)
.OfType<string>(v => Console.WriteLine($"{v} is a string"))
.OfType<DateTime>(v => Console.WriteLine($"{v} is a DateTime"))
.OfType<int>(v => Console.WriteLine($"{v} is an integer"))
.OfType<object>(v => Console.WriteLine($"{v} is an object"))
);
f(DateTime.Now);
f("Hello, world!");
f(13);
f(0.45);

And finally, here is the solution to the famous FizzBuzz test, using this construct:
for (var i = 0; i < 100; i++)
{
Do.Switch(i)
.If(v => v % 15 == 0, v => Console.WriteLine($"FizzBuzz"))
.If(v => v % 3 == 0, v => Console.WriteLine($"Fizz"))
.If(v => v % 5 == 0, v => Console.WriteLine($"Buzz"))
.Default(v => Console.WriteLine($"{v}"));
}

Now, the question is how does this fare against the traditional switch? How much overhead does it add if we would, let's say, take all switch/case blocks and replace them with this construct? This brings me to the idea of using AOP to check if the construct is of a certain shape and then replace it with the most efficient implementation of it. With the new Roslyn compiler I think it is doable, but beyond the scope of this post.

I have tried, in the few minutes that it took to write the classes, to think of performance. That is why I cache the value type, although I don't think it really matters that much. Also note there is a difference between Case(v=>SomeMethodThatReturnsAValue(),DoSomething()) and Case(SomeMethodThatReturnsAValue(),DoSomething()); In the first case, SomeMethodThatReturnsAValue will only be executed if the switch has not matched something previously, while in the second, the method will be executed to get a value and then, when the time comes, the switch will compare it with the initial value. The first method is better, with only 4 extra characters.

Hope it helps someone.

Nemesis Games (The Expanse book 5), by James S.A. Corey

book cover Nemesis Games felt like a fixer-upper. The authors had already established a pattern in the books from The Expanse, mainly a psychopathic villain and the motley crew of the Rocinante saving the world through bouts of coincidence and luck that are impossible to believe, and so seeing the exact same formula used again in the fifth book was a disappointment. However, they had another issue: the characters of the story were not very clearly defined. Having hinted since forever that each of the people on the ship had a heavy past, James S.A. Corey decided to explain almost all of those pasts in this book. The fact that the disaster was epic made the book easy to read through, in that "what happens next" trance, but it felt the book version of an elevator show. It even ended badly, with conflicts unresolved and a cliffhanger "to be continued" scene at the end. The sixth book of the series, Babylon's Ashes, is supposed to be published in April this year and seriously I am asking myself if I want to continue reading it.

To be honest, the book was not bad. It was just so recklessly slapped together using book writing rules that it felt like a commercial TV show. And I don't mean one of the good ones like, ironically, the first season of The Expanse, I mean those long winded cop shows that lead to nothing. I wasn't the only one to notice that the characters in the series have not really evolved one bit since they were introduced, despite having passed through five separate world saving scenarios. Taking a page from their mentor, George R.R. Martin, the authors just let the alien presence linger in the shadows, having no role whatsoever besides the one of stage prop. Meanwhile, all the conflict, all the struggle is between ordinary humans. This appeals, but then it bores. And yes, I have to admit to myself, the feeling I am left with after reading Nemesis Games is boredom.

Perhaps if at least one of the books would have explained the actions and motivations and background of the villains, other than being sick in the head, I would have liked the series more. I know that there are short novellas that try to do that and I did try to read some, but after a few tens of pages I gave up. If the books feel like an endlessly rehashed formula, the novellas feel like those quotes from fictional people and books that some sci-fi writers adorn their chapters with. If I make efforts to feel anything for the people in the books, I feel absolutely nothing for the sketched out secondary characters in the novellas.

So there, after reading the five books one after the other like there was no tomorrow, my final verdict is 'meh'. Perhaps they should have hired Brandon Sanderson to finish up the series. That guy is good at that. Hey, Brandon, can you write three books in The Expanse, starting from the second book, Caliban's War, and ignoring the rest?

Saturday 12 March 2016

C# equivalent to F# Active Patterns

active patterns in F# code F# has an interesting feature called Active Patterns. I liked the idea and started thinking how I would implement this in C#. It all started from this StackOverflow question to which only Scala answers were given at the time.

Yeah, if you read the Microsoft definition you can almost see the egghead that wrote that so that you can't understand anything. Let's start with a simple example that I have shamelessly stolen from here.
// create an active pattern

let (|Int|_|) str =
match System.Int32.TryParse(str) with
| (true, int) -> Some(int)
| _ -> None

// create an active pattern

let (|Bool|_|) str =
match System.Boolean.TryParse(str) with
| (true, bool) -> Some(bool)
| _ -> None

// create a function to call the patterns

let testParse str =
match str with
| Int i -> printfn "The value is an int '%i'" i
| Bool b -> printfn "The value is a bool '%b'" b
| _ -> printfn "The value '%s' is something else" str

// test

testParse "12"
testParse "true"
testParse "abc"

The point here is that you have two functions that return a parsed value, either int or bool, and also a matching success thing. That's a problem in C#, because it is strongly typed and if you want to use anything than boxed values in objects, you need to define some sort of class that holds two values. I've done that with a class I called Option<T>. You might want to see the code, but it is basically a kind of Nullable class that accepts any type, not just value types.
Click to expand

Then I wrote code that did what the original code did and it looks like this:
var apInt = new Func<string, Option<int>>(s =>
{
int i;
if (System.Int32.TryParse(s, out i)) return new Option<int>(i);
return Option<int>.Empty;
});
var apBool = new Func<string, Option<bool>>(s =>
{
bool b;
if (System.Boolean.TryParse(s, out b)) return new Option<bool>(b);
return Option<bool>.Empty;
});

var testParse = new Action<string>(s =>
{
var oi = apInt(s);
if (oi.HoldsValue)
{
Console.WriteLine($"The value is an int '{oi.Value}'");
return;
}
var ob = apBool(s);
if (ob.HoldsValue)
{
Console.WriteLine($"The value is an bool '{ob.Value}'");
return;
}
Console.WriteLine($"The value '{s}' is something else");
});

testParse("12");
testParse("true");
testParse("abc");

It's pretty straighforward, but I didn't like the verbosity, so I decided to write it in a fluent way. Using another class called FluidFunc that I created for this purpose, the code now looks like this:
var apInt = Option<int>.From<string>(s =>
{
int i;
return System.Int32.TryParse(s, out i)
? new Option<int>(i)
: Option<int>.Empty;
});

var apBool = Option<bool>.From<string>(s =>
{
bool b;
return System.Boolean.TryParse(s, out b)
? new Option<bool>(b)
: Option<bool>.Empty;
});

var testParse = new Action<string>(s =>
{
FluidFunc
.Match(s)
.With(apInt, r => Console.WriteLine($"The value is an int '{r}'"))
.With(apBool, r => Console.WriteLine($"The value is an bool '{r}'"))
.Else(v => Console.WriteLine($"The value '{v}' is something else"));
});

testParse("12");
testParse("true");
testParse("abc");

Alternately, one might use a Tuple<bool,T> to avoid using the Option class, and the code might look like this:
var apInt = FluidFunc.From<string,int>(s =>
{
int i;
return System.Int32.TryParse(s, out i)
? new Tuple<bool, int>(true, i)
: new Tuple<bool, int>(false, 0);
});

var apBool = FluidFunc.From<string,bool>(s =>
{
bool b;
return System.Boolean.TryParse(s, out b)
? new Tuple<bool, bool>(true, b)
: new Tuple<bool, bool>(false, false);
});

var testParse = new Action<string>(s =>
{
FluidFunc
.Match(s)
.With(apInt, r => Console.WriteLine($"The value is an int '{r}'"))
.With(apBool, r => Console.WriteLine($"The value is an bool '{r}'"))
.Else(v => Console.WriteLine($"The value '{v}' is something else"));
});

testParse("12");
testParse("true");
testParse("abc");

As you can see, the code now looks almost as verbose as the original F# code. I do not pretend that this is the best way of doing it, but this is what I would do. It also kind of reminds me of the classical situation when you want to do a switch, but with dynamic calculated values or with complex object values, like doing something based on the type of a parameter, or on the result of a more complicated condition. I find this fluent format to be quite useful.

One crazy cool idea is to create a sort of Linq provider for regular expressions, creating the same type of fluidity in generating regular expressions, but in the end getting a ... err... regular compiled regular expression. But that is for other, more epic posts.

The demo solution for this is now hosted on Github.

Here is the code of the FluidFunc class, in case you were wondering:
public static class FluidFunc
{
public static FluidFunc<TInput> Match<TInput>(TInput value)
{
return FluidFunc<TInput>.With(value);
}

public static Func<TInput, Tuple<bool, TResult>> From<TInput, TResult>(Func<TInput, Tuple<bool, TResult>> func)
{
return func;
}
}

public class FluidFunc<TInput>
{
private TInput _value;
private static FluidFunc<TInput> _noOp;
private bool _isNoop;

public static FluidFunc<TInput> NoOp
{
get
{
if (_noOp == null) _noOp = new FluidFunc<TInput>();
return _noOp;
}
}

private FluidFunc()
{
this._isNoop = true;
}

private FluidFunc(TInput value)
{
this._value = value;
}

public static FluidFunc<TInput> With(TInput value)
{
return new FluidFunc<TInput>(value);
}

public FluidFunc<TInput> With<TNew>(Func<TInput, Option<TNew>> func, Action<TNew> action)
{
if (this._isNoop)
{
return this;
}
var result = func(_value);
if (result.HoldsValue)
{
action(result.Value);
return FluidFunc<TInput>.NoOp;
}
return new FluidFunc<TInput>(_value);
}

public FluidFunc<TInput> With<TNew>(Func<TInput, Tuple<bool,TNew>> func, Action<TNew> action)
{
if (this._isNoop)
{
return this;
}
var result = func(_value);
if (result.Item1)
{
action(result.Item2);
return FluidFunc<TInput>.NoOp;
}
return new FluidFunc<TInput>(_value);
}

public void Else(Action<TInput> action)
{
if (this._isNoop) return;

action(_value);
}

}

Friday 11 March 2016

Cibola Burn (The Expanse book 4), by James S.A. Corey

book cover Cibola Burn is the book that worried me the most. James S.A. Corey had created a world in which the Solar System has been colonized and Abaddon's Gate, the third book in the Expanse series, had ended with humanity gaining access to one thousand new star systems. I liked the Solar System background and I really thought the fourth book was gonna suck. Well, while being some of the same old thing as the other books and maybe even better written - so a better book - it also sucked because I could easily imagine Picard and The Enterprise going on a mining colony to settle a territorial dispute and, beside being PG-13, having almost nothing changed.

The plot of the book is about Holden and the Rocinante being sent to mediate a situation between the representatives of an Earth corporation and the people who had landed on the planet before the corporation had even filed a claim. You have your familiar characters like the crew of the Rocinante and Miller and even Havelock (Miller's former partner, now a security employee of the Earth corporation), you have your psychotic leader types that mess everything up while the good guys hesitate to just shoot them, you have the very human characters with children that need to be saved, you have the overwhelming but dumb alien presence and the snowballing crisis that drives it all. I thought the story was a bit of a rehashing of the same ideas and therefore I enjoyed it less than I would have if I had read it standalone. I know that successful series are based on successful books and must present kind of the same so to not alienate its readers, but as the intergalactic situation changes dramatically, damn if I don' feel the plot should vary a little, too.

Given that science and technology have always played a big part in the Expanse, you get to see more attention to the details than from other authors, but so far Cibola Burn felt to me like the least scientifically accurate so far. And yet I liked it, because it is well written and it drives the reader through the story and makes most characters likable and one wonders what the hell would they do if they were in the character's shoes.

Cibola is the Spanish transliteration of a native name for a pueblo (Hawikuh Ruins) conquered by Francisco Vásquez de Coronado, also one of the seven mythical gold cities that the conquistadors searched for in vain.

Tuesday 8 March 2016

The Sicilian Wing Gambit - Revisited

I've been monitoring more closely the access to my blog and I noticed that a lot of people are interested in the post about the Sicilian Wing Gambit, defined as pushing b4 in reply to the standard Sicilian Defense e4 c5. So I will be trying in this to use new knowledge and computer engines to revisit this funky opening gambit. As such I will be using LiveBook, a system created by the people at ChessBase that tries to catalog and discover chess based on active chess games and analysis, as well as computer engines, in this case Komodo 9 with a 256MB table memory. I've continued each variation until there was only 1 game left in the database, then I stopped.

Main line from LiveBook


Let's start with LiveBook. Here is a PGN with the main variations in order of use. You will notice that the main line is to accept the gambit (GM Jan Gustafsson even wrote "take the pawn and be happy!" at that particular junction), then refuse the second pawn and immediately challenge the center - which would have been the Sicilian idea all along - by pushing d5. It loks a bit like a Scandinavian Defense, but without White being able to push the Black queen back with Nc3. The main line shows Black gaining advantage, but then losing it by move 12, where equality sets in. However, the computer does not recognize some of the moves in the main line as best.

In the line that I was interested in, the one where Black takes the pawn on the a-file, White gains the classical center and technically it is ahead in deployment of minor pieces, if one considers a knight on the a-file and a semi blocked in bishop developed pieces. However, not all is lost, as the computer has some ideas of its own. Also keep in mind that the Sicilian Wing Gambit is not well known and few people actively employ it.

So here is the PGN of the LiveBook database, based on what people played: 1. e4 c5 2. b4 {This is the Sicilian Wing Gambit. From here on, the percentages in the comments are wins for White and the points are from computer engines.} cxb4 (2... b6 3. bxc5 bxc5 4. Nc3 Nc6 5. Rb1 g6 6. g3 Bg7 7. Bg2 Ba6 8. Nge2 {50% / 0.00}) 3. a3 d5 (3... bxa3 4. Nxa3 d6 5. d4 Nf6 6. Bd3 Nc6 7. c3 e5 8. Ne2 {50% / -0.33}) (3... e6 4. axb4 Bxb4 5. Bb2 (5. c3 Be7 6. d4 d6 7. Bd3 Nf6 8. Ne2 Nc6 9. O-O O-O) 5... Nf6 6. e5 Nd5 7. c4 Ne7 8. Na3 (8. Qg4 Ng6 9. h4 h5 10. Qg3 Nc6 11. Bd3 {50% / -0.75}) 8... Nbc6 9. Nc2 Ba5 {50% / -0.25}) 4. exd5 Qxd5 5. Nf3 (5. Bb2 e5 6. Nf3 Nc6 7. c4 Qe6 8. Bd3 Nf6 9. O-O
Bd6 10. Re1 O-O 11. axb4 Nxb4 12. Bf1 {75% / 0.00}) 5... e5 6. Bb2 (6. axb4 Bxb4 7. c3 Be7 8. Na3 Nc6 9. Nb5 Qd8 10. d4 exd4 11. Bf4 Kf8 12. Nbxd4 Nxd4 13. Nxd4 {50% / 0.00}) (6. c4 Qe6 7. Bd3 Nc6 8. Bb2 Nf6 9. O-O Bd6 10. Re1 O-O 11. axb4 Nxb4 12. Bf1 {75%}) 6... Nc6 7. c4 Qe6 8. Bd3 Nf6 9. O-O Bd6 10. Re1 O-O 11. axb4 Nxb4 12. Bf1 e4 13. d3 Qd7 14. dxe4 Bc5 15. Bxf6 Qxd1 16. Rxd1 gxf6 {50% / 0.00} *


Computer analysis: main line


Now let's put Komodo on the job, let us know what is going on here. Many people analysed the position resulting after pushing b4 and with depths of 36 and 40, computer engines overwhelmingly suggest taking the pawn. However we might want to explore what happens if we take another option. It is interesting to note that Komodo 9 pushes the main move as the third most important at depth 24. Perhaps later on this would get reversed again, but this soon into the game it just tells us that the other options are equally good. The two moves I am talking about is d5 and e5. Interestingly enough, the second most common human move (b6) is not even on the radar for the computer, while the computer move appears to have been played only 4 times by humans. So let's take a look at computer moves:1. e4 c5 2. b4 d5 3. exd5 cxb4 4. a3 Qxd5 5. Nf3 e5 6. axb4 Bxb4 7. c3 e4 8. cxb4 exf3 9. Qxf3 Qxf3 10. gxf3 * At the end of all this, White has four pawn islands and doubled pawns, but can quickly use the semi open files to attack with rooks. Maybe this discourages you, but remember two things: these are computers making these moves and while the position looks weird, you get attacking chances with no loss of material. That is the purpose of a gambit after all.

Computer analysis: accepting both pawns


Let's see what computers say about the line that we want to happen. The gambit is accepted, the a-pawn is captured as well. What then? I was surprised to see that, depending on depth and engine, the next move is quite different. Stockfish 6, at depth 39 goes with d4, taking control of the center and ignoring the Black a-pawn. The variations from this position are quite complex and have less to do with this gambit. I would gamble (pardon the pun) that the purpose of the wing gambit was reached at this point. Computers give a clear equality between players, but remember that even after we capture the a-pawn, we have still would be a pawn down. Black is forced to passive moves like e6, d6, having to spend resources to regain center control, while most White pieces have clear attack lines.

An example: 1. e4 c5 2. b4 cxb4 3. a3 bxa3 4. d4 e6 5. Nf3 d5 6. e5 Bd7 7. Bd3 Nc6 8. Nxa3 Bb4+ 9. Bd2 Bxd2+ 10. Qxd2 a6 *

Computer analysis: accepting just the first pawn


But what happens in between these two options? What if Black accepts the gambit, but doesn't take the second pawn? Will the computer see the same result as in the "human main line" we first discussed? Not quite. The computer moves are really different from the human ones. 1. e4 c5 2. b4 cxb4 3. a3 e5 4. Nf3 Nc6 5. Bb2 Nf6 6. Nxe5 Qe7 7. Nf3 Nxe4 8. Be2 d5 9. O-O Qd8 10. Bb5 bxa3 11. Nxa3 Bc5 * The result is another equal position, where White lost the center, but has a strong, yet weird development.

Also check out 3... d5: 1. e4 c5 2. b4 cxb4 3. a3 d5 4. exd5 Qxd5 5. Nf3 e5 6. axb4 Bxb4 7. c3 e4 8. cxb4 exf3 9. Qxf3 Qxf3 10. gxf3 Ne7 * An interesting tactic is not to take the d5 pawn and instead advance the e-pawn to e5: 1. e4 c5 2. b4 cxb4 3. a3 d5 4. e5 Nc6 5. Bb2 Qb6 6. Nf3 Bg4 7. axb4 Qxb4 8. Bc3 Qe4+ 9. Be2 Bxf3 10. gxf3 Qf4 11. d4 * You can watch an example game in this variation from Kingscrusher.
My opinion on this is that White forces a strong center, but, as seen from the computer variation, the sides get seriously compromised. The truth is that I always wondered if there is a solid play with the king in the center. This might be it, although keep in mind that in that position White is a pawn down.

What if we start with b4 and then try to move towards the center?


Well, that's easy to answer: it's another opening :) called the Polish or Sokolsky opening and I have written another blog post about it, although it is pretty old. Maybe I will also revisit that one. The point with that opening is that it already shows Black what we plan and it has some other principles of work, more closely related to the English opening to which it sometimes transposes. The Wing Gambit, though, is a response to the Sicilian, trying to pull the opponent from their comfort zone and into ours.

What if we delay the b4 push?


One can wait for the wing gambit until knights have left their castle. That's called the Portsmouth Gambit (1. e4 c5 2. Nf3 Nc6 3. b4) and some consider it stronger than the gambit presented here. It might be interesting to analyse. Haven't found a lot of resources on it, just this 2014 book from David Robert Lonsdale.

Another option is to play 3. a3, preparing a support of b4 on the next move. It does produce similar results as the base gambit, but I didn't have time to analyse it and it feels a bit slow, to be honest.

When Black defends with b6


Defending c5 with b6 leads to a Sicilian without the b-pawns. That means that an attack on the queen side is out and the White light square bishop can linger around on the queen side as long as it wants, targeting that juicy Black king side from afar. Combine that with the dark square bishop having a nice diagonal as well. 1. e4 c5 2. b4 b6 3. bxc5 bxc5 4. Nf3 Nc6 5. Bb5 Nd4 6. Nxd4 cxd4 *
For an example of that variation, check out Kingscrusher's video.

Traps in the Sicilian Wing Gambit


I couldn't find a lot of traps in the Sicilian Wing Gambit. One good video on this comes from GJ_Chess (ignore his Indian accent, he is actually quite good and, what I like a lot, he focuses on traps and dirty tricks in his videos):


Other ideas and nomenclatures


The ECO category for this opening is B20, same as for the Sicilian Defense, which doesn't help a lot.

After Black captures the b-pawn, c4 is called the Santasiere variation of the Wing Gambit, and Black's only option seems to try for control of d4 with either e5 or Nc6. Taking en-passant is giving White a lot of compensation in development.

The goading of the Black pawn with a3 that we've covered above is called the Marshall variation. If Black pushes the pawn to d5 and White captures, we enter the Marienbad variation, while if Black captures the a-pawn, it is called Carlsbad variation. For the record, bad is the German name for bath not an indication that the variation is bad :).

Pushing a3 before b4 is called the Mengarini gambit. Check out a game from 2013 between Dobrov and Blom.

Other resources on the gambit


A nice review of this gambit, with names of the variations and some human analysis, can be found on chess.com. (The same author has a post on The Portsmouth Gambit as well)

On chesstempo there is a nice list of games with this variation that you can search. Play around with the Advanced Search parameters. As a reference, there are 11 games from people over 2500 using the Wing Gambit and White has most wins. If restricting to games after 2000, you only get one, which ended in a draw, although White was better at the end. You can see the game here: Timur Gareev vs Gata Kamsky, US Championship (2015).

Interesting Wing Gambit/Fried Liver attack combo that you can see here: John P. Pratt vs Elden Watson, 29 Sep 1976, Hill Air Force Base, Utah. You gotta love that. Not the best rated players in the world, but still. Here is a lichess computer analysis of the same game.

A 2013 call to reevaluate the Wing Gambit with some examples of famous old games where the opening had a strong effect.

Conclusions


Unlike the Sokolsky opening, the purpose of the Sicilian Wing Gambit is not to push the b-pawn to block Black's development, but to deflect the c-pawn from protecting the center. The goal is reached when White has a strong center. In no way does it mean it is a winning gambit. There are no brutal traps, no quick wins, the only purpose of this opening is to pull an aggressive Sicilian player from their comfort zone and into a slower, more positional one. That means that the White player needs to attack like crazy until Black is a mere smear on the board, otherwise the center control and speed advantage that may be obtained from the opening can be easily lost.

From my analysis I gather that Black should accept the gambit, but not continue to take pawns like the a-pawn, instead focusing on their own piece development and control of the center. With perfect computer play, equality is reached and maintained. White often fianchettoes the dark square bishop to b2 from where they put pressure on the Black king side. Black's game often centers on exchanging pieces, so that the opening advantage gets lost. The best chance Black has to decline the gambit seems to be pushing d5, going into murky territory.

White on the other hand should push for the center, even propping the d-pawn with c3 and blunting the dark square bishop diagonal. Then focusing on attack is the most important feature, as in most gambits.

Careful with the variation in which Black attacks the e4 pawn with d5, then capturing with the queen after the exchange. If not careful the queen can fork the king and the rook. That is why Nf6 is played by White as the next move or even Bb2, although that's not as good, as the bishop can be deflected.

Usually the a-pawn is recaptured with the knight, not the bishop. This may seem surprising, but what it prepares is moving the knight on b5, attacking c7 and a7 and being very hard to dislodge, as the a-pawn is pinned to the rook. Some variations sacrifice the Black rook in the corner for a quick counter-attack. In case it is captured with the bishop, the idea is to exchange dark square bishops and prevent the Black king from castling.

In several games I have seen, moving towards the center forces Black to use e6 followed by d5, to which White can respond with e5 themselves and get into French defense territory. Personally I dislike playing against the French, but in this case, without b-pawns, the theory is quite different as well. For an example, check out this video from Kingscrusher.

Even if caustic GM Roman Dzindzichashvili categorized this as the worst opening for White, don't forget that it was used by Fischer in 1992 to beat Spassky. Well, a transposition thereof. If you are confident in your chess skills, this is just as good an opening as any other and at least you need to know it a little in order to defend against it.

I would love some comments from some real chess players, as all of this is based on game databases and computer analysis. Please leave comments with what you think.

Video examples


Here is Simon Williams using the gambit against a young Polish player:


ChessTrainer shows a nice game where he uses the gambit to get a quick center and take his opponent out of Sicilian main lines:


MatoJelic is showing us some classical games:
Thomas A vs Schmid, Hastings 1952

Wood L vs Mease A ,USA, 1949

Monday 7 March 2016

COMA concert in Bucharest, at Fabrica, on the 5th of March

Pava and Dan Costea Coma is my favorite Romanian bands and I've known them almost since they were formed. They have been singing for 16 years now and it was nice to see the concert room filled with people of all ages, including a 16 year old boy who had his birthday on the same day. For me this concert was a double whammy, as the lead singer of one of the opening bands is a former colleague of mine. Yeah, small world.

The opening bands where Till Lungs Collapse and Pinholes. TLC were nice, with my boy Pava almost collapsing his lungs. Pinholes were a bit strange: from five people on the stage, only the drummer didn't sport a guitar. Their writing process must be weird. Then Coma came on stage, at about 0:00 and played for an hour an a half. They were great! I've been to many of their concerts and this is one of the best yet. The band's "curse" struck again, on Dan Costea's acoustic guitar, but they were able to continue without it with no problems. They sang all time favorites, some newer songs, they also did Morphine, which is one of my personal favorite songs of theirs. I wish they would have managed to squeeze Daddy in there, or at least 3 Minute.

Catalin Chelemen was on fire, Dan was doing his usual PR thing and he was great as well and it seemed like they all had a good chemistry with the new guitar player, Matei Tibacu. Well, new for me. Unfortunately the sound in Fabrica was pretty bad. While inside you could kind of focus on the right notes, especially if you knew what the songs were supposed to play like, if you try to gauge the quality of the concert from the videos that are online now, you want to mute it almost instantly. People were respectful enough not to smoke during the concert (I can't wait for the smoking ban to come in effect!), but my clothes still smelled of tobacco when I got home, from people smoking in the next room.

As far as I know you can hear them next at the Electric Castle Festival, July 14-17, with so many other great bands. I am tempted to go there, but I am not one for festivals. Great job, Coma, and good luck!

Click here to see some nice photos from the concert.