Roberto Selbach

About |  Blog |  Archive

Author: Roberto Selbach

Roberto Selbach Teixeira is a father, a husband, a software developer, a skeptic, a humanist, and a lot more.

Returns in Go and C#

Whenever someone posts anything related to the Go programming language on Hacker News, it never takes long before someone complains about error handling. I find it interesting because it is exactly one of things I like the most about Go.

I don’t want to specifically talk about error handling though. I want to talk about a feature that is intrinsically tied to it in Go: the ability of functions to return multiple values

For instance, in Go it is common and idiomatic to write functions like this —

func Divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0.0, errors.New("divide by zero")
    }
    return a / b, nil
}

So the caller would do:

result, err := Divide(x, y)
if err != nil {
    // do error handling...
}

Some people deplore this. I absolutely love it. I find it so much clearer than, for instance, what we often have to do in C#. You see, C# didn’t have multiple returns (until very recently; see below) so you ended up with a few options.

First, you can simple throw exceptions.

public SomeObject GetObjectById(int id) {
    if (!SomeObjectRepo.Has(id))
        throw new ArgumentOutOfRangeException(nameof(id));
    // ...
}
...
try
{
    var obj = GetObjectById(1);
    // do something with obj
}
catch (ArgumentOutOfRangeException ex)
{
    //  error handling
}

I find the flow difficult to read. Particularly because variables are scoped within the try-catch so often you need to first declare something above the try and then test it after the catch.

A second option is to return null:

public SomeObject GetObjectById(int id)
{
    if (!SomeObjectRepo.Has(id))
        return null;

    // go get the object
}
...
var obj = GetObjectById(1);
if (obj == null) 
{
    // do error handling
}

This looks closer to what I like but it still has some serious downsides. You don’t get any error information. What made it fail? I don’t know. As well, this doesn’t work for non-nullable types. A method returning a, say, int cannot return null. Sure, you could return int? instead of int and then test for .HasValue but that’s cumbersome and artificial.

A third option is the use of a generic return type. Something like —

public class Result<T>
{
    public T Value {get;protected set;}
    public Exception Exception {get; protected set;}

    public bool IsError => Exception != null;

    public Result() : this(default(T)) {}
    public Result(T value)
    {
        Value = value;
    }

    public static Result<T> MakeError(Exception exception)
    {
        return new Result<T>
        {
            Value = default(T),
            Exception = exception
        };
    }
}

You could then use this to return values like —

public Result<int> Divide(int a, int b)
{
    if (b == 0)
    {
        return Result<int>.MakeError(new DivideByZeroException());
    }

    return new Result<int>(a / b);
}
...
var res = Divide(8, 4);
if (res.IsError)
{
    // do error handling, e.g.
    throw res.Exception;
}
// do something with res.Value (2)

This works, but it looks artificial. You need to create instances of Result<T> all around all the time. It is not that bad if your codebase uses this throughout and it becomes automatic for all programmers envolved. When it’s an exception to the rule, it is horrible.

A very similar solution is to return something like Tuple<T1, T2, ...>

public Tuple<int,Exception> Divide(int a, int b)
{
    if (b == 0)
        return new Tuple<int,Exception>(0, new DivideByZeroException());
    return new Tuple<int,Exception>(a/b, null);
}
...
var res = Divide(1, 2);
if (res.Item2 != null) // Item2 is the exception
{
    // do error handling
}
// do something with res.Item1

Same principle. It’s ugly and artificial, but it will come back to us.

The way the C# authors found to work around this problem is the idiomatic try-pattern, which consists in creating non-exception-throwing versions of methods. For example, if we go back to the first C# example above (GetObjectById()), we could create a second method like so —

public bool TryGetObjectById(int id, out SomeObject result) {
    try 
    {
        result = GetObjectById(id);
        return true;
    }
    catch
    {
        result = default(SomeObject);
        return false;
    }
}
...
SomeObject result;
if (!TryGetObjectById(1, out result))
{
    // do error handling
}
// do something with result

Note that ever since C# 7.0 you can declare the out variable directly inside the method call as such —

if (!TryGetObjectById(1, out var result))

Which spares you of declaring your out variables arguably at the expense of clarity.

This method is idiomatic and found everywhere in the .NET Framework. I actually like it but it still has the problem of losing important information, namely what caused the method to fail: all you get is true or false.

In C# 7.0, the language authors came up with a new solution: they added syntactic sugar to the language to make the tuple solution a bit more appealing —

public (int, Exception) Divide(int a, int b)
{
    if (b == 0)
        return (0, new DivideByZeroException());

    return (a / b, null);
}
...
var (res, err) = Divide(1, 2);
if (err != null) 
{
    // do error handling
}

Suddenly this becomes very familiar to a Go programmer. In the background, this is using a tuple. In fact, you can check that this is so by using the method above like this —

var res = Divide(1, 2);
if (res.Item2 != null)
    // do error handling
// use res.Item1

You will see that res is of type System.ValueTuple. Also, if you create a library in C# 7.0 and then try to use it with a program in older versions of C#, you will see that the exposed type of the method is a tuple. This is actually nice because it means this big language change is backwards compatible.

All that said, I haven’t seen many uses of the new tuple returns in C# code in the wild. Maybe it’s just early (C# 7.0 has been out for only a few months.) Or maybe the try-pattern is simply way too ingrained in the way of doing things in C#. It’s more idiomatic.

I sure prefer the new (Go-like) way.

Casting objects and boxing

I’m back from a trip to a customer.

How was it?

Okay. I got more snow that I expected on the way there, so the drive wasn’t much fun. Then again, a part of the trip goes through a beautiful forest that was worth everything else.

Cool!

Also, while showing the customer a new feature, the app crashed.

Typical. Blame it on Murphy!

That’s what I did at first. Then I blamed it on the developer. And then I finally went looking at the C# code to find out why it happened.

What was it?

It turned out to be a rather common but not obvious mistake. See the code below and tell me what is the value of each of doubleF, doubleI, and doubleO.

float f = 0.0;
int i = (int)f;
object o = f;

var doubleF = (double) f;
var doubleI = (double) i;
var doubleO = (double) o;

I’m sensing a catch here, but I’ll bite. They’re all cast from the same original variable f so I’m guessing they’d all end up 0.0…?

You would, wouldn’t you? But you’re wrong.

Waaat?

The final line in that code will throw an InvalidCastException at you — and crash your app if you don’t catch it, as was the case in our app.

Wait what? How? How come you can’t cast 0.0 to double?

Well, you can. For instance, this works perfectly —

var d = (double) 0.0f;

But this doesn’t —

object f = 0.0f;
var d = (double) d;

It makes no sense!

Actually it does. The problem is taking object to mean “anything.” Which incidentally it does, just not the way most people think. You see, object is a type representing Object, which is a class other types inherit from but not all. You can store anything as object because Object boxes whatever object you put in it. It stores the value internally but the compiler doesn’t know what type is stored there.

No no no! I know for a fact that you can too check what type is stored in an object

You’re right, you can. For instance —

object o = /* something */
Console.WriteLine(o.GetType());

This will print the type of whatever you put in the variable o. But this is at run time: the compiler doesn’t know.

That’s why we using casting. If we know for a fact that variable o will contain a, say, int, we can help the compiler and tell it about it with a cast. Remember, when you cast something, you are telling the compiler what type will be stored in the variable. The compiler can’t be held responsible if you lie to it.

Let’s get back at the original problem —

object o = 1.0f;
var d = (double) o;

You told the compiler that o will be a double, but it isn’t. Remember a double is a shorthand for the struct Double as float is for Single. And guess what? A Double is not a Single. When you stored a float in the variable o of type object, the float value was boxed inside an object of type Object. When you cast, the compiler has to unbox whatever was inside o and guess what, the value stored in o is of a different structure, with different methods and storage, than what you told it it was. You could convert between them, but they are not the same.

So the compiler expects an object of type Double but it has a Single and things fail miserably.

But you just said that we can convert between them! Why don’t the compiler does it?

It could. But think of how this would work out in real life. Remember the compiler doesn’t know what will be inside o so it needs to test what the value is. It would need to test if the type is a, say, string. If it is, then convert string to Double. If it isn’t then check if it is a Int32. Then a Int64. Then a DateTime. The number of possibilities is enormous and the compiler would have to generate all this code every time it needs it finds a cast. This would be a lot of code. It would be so much code in fact that you’d be mad not to put it all in separate methods. It would also be slow so the compiler won’t do this by default.

That’s why we have the Convert class, which in turn depends on types implementing the IConvertible interface. Whenever you want to convert a value of TypeA to TypeB, you can use this conversion methods. You can do —

object o = 1.0f;
var d = Convert.ToDouble(o);

The compiler authors had to make a decision: either they’d generate lots of slow code to test for the type and convert the value, or they’d leave the decision for the programmer who can call Convert.ToSomething when needed.

And they chose the former.

Exactly. I believe it was reasonable. If you know something will be of a given type at run time, you can still cast it. Otherwise, you should convert it.

Retreating back into my bubble

A few months back I decided to try and burst out of my bubble. I then decided to follow some public figures from all sides on Facebook and Twitter. On Facebook this is particularly weird because you’re forced to like the page. So it tells the world “Roberto likes Mrs. Public-Figure”, which is sometimes undesirable.

Still, I wanted to see what both sides of the political spectrum were saying. Also, I consider myself a centrist so I expected to agree with everyone on at least something.

Anyway, my town suffered a terrorist attack a couple of days ago and as soon as the identity of the suspect became known, the media started drawing conclusions based on who he “liked” on Facebook. That got me thinking: someone will eventually go through my social media and conclude I believe in X because I “like” Y on FB, even though I may only “like” Y because I want to be informed and not because I necessarily agree with them.

There are also reports that US Border agents now require people to provide social network credentials so that their political leanings can be attested. Regardless on my personal opinions about this, the fact is that someone with access to my FB account can quickly draw the conclusion that I lean this or that way because of the pages I like, even though I liked them only to be informed.

I then realized that it’s time to give up on my bubble-bursting experiment. I “unliked” pretty much every public figure on Facebook.

Cedilha no Fedora 25

Quem utiliza teclado US Internacional para escrever no Linux já deve ter dado de cara com o fato de que na maioria das distribuições, a combinação ‘+c gera um “ć” em vez de um “ç”. Resolver isso no Fedora 25 é fácil, mas não evidente.

tl;dr – eu criei este script que faz todos os passos abaixo automaticamente. Basta rodar isso:

curl https://raw.githubusercontent.com/robteix/c-cedilla-fedora/master/c-cedilla-fedora | bash

Se você preferir não executar o script, continue lendo.

Primeiro, vamos criar um novo mapa de teclado para seu usuário. Rode o comando abaixo:

sed -e 's,\xc4\x86,\xc3\x87,g' \
    -e 's,\xc4\x87,\xc3\xa7,g' \
    < /usr/share/X11/locale/en_US.UTF-8/Compose > ~/.XCompose

Isso copia o arquivo de mapeamento de teclas do Fedora para o diretório $HOME do usuário, substituindo o “Ć” por um “Ç”.

Agora vamos configurar o GNOME para que ele não controle a configuração do teclado, para que possamos usar nossa própria:

gsettings set org.gnome.settings-daemon.plugins.keyboard active false

Para selecionar o input method apropriado, o Fedora fornece um programinha chamado im-chooser que não é instalado por padrão. Para instalá-lo:

sudo dnf install im-chooser

Por fim, executamos o im-chooser e escolhemos “Use X Compose table”:

Clique em “Log out” para aplicar as modificações e a partir de agora deve ser possível gerar o c-cedilha com a combinação ‘+c.

The Woman the Mercury Astronauts Couldn’t Do Without

Must-read article on “human computer” Katherine Johnson. Not only was she a key figure in pushing NASA’s efforts forward, but she did it while fighting misogyny and racism:

Outside the gates, the caste rules were clear. Blacks and whites lived separately, ate separately, studied separately, socialized separately, worshipped separately, and, for the most part, worked separately. At Langley, the boundaries were fuzzier. Blacks were ghettoed into separate bathrooms, but they had also been given an unprecedented entrée into the professional world. Some of Goble’s colleagues were Yankees or foreigners who’d never so much as met a black person before arriving at Langley. Others were folks from the Deep South with calcified attitudes about racial mixing. It was all a part of the racial relations laboratory that was Langley, and it meant that both blacks and whites were treading new ground together. The vicious and easily identifiable demons that had haunted black Americans for three centuries were shape-shifting as segregation began to yield under pressure from social and legal forces. Sometimes the demons still presented themselves in the form of racism and blatant discrimination. Sometimes they took on the softer cast of ignorance or thoughtless prejudice. But these days, there was also a new culprit: the insecurity that plagued black people as they code-shifted through the unfamiliar language and customs of an integrated life.

Katherine understood that the attitudes of the hard-line racists were beyond her control. Against ignorance, she and others like her mounted a day-in, day-out charm offensive: impeccably dressed, well-spoken, patriotic, and upright, they were racial synecdoches, keenly aware that the interactions that individual blacks had with whites could have implications for the entire black community. But the insecurities, those most insidious and stubborn of all the demons, were hers alone. They operated in the shadows of fear and suspicion, and they served at her command. They would entice her to see the engineer as an arrogant chauvinist and racist if she let them. They could taunt her into a self-doubting downward spiral, causing her to withdraw from the opportunity that Dr. Claytor had so meticulously prepared her for.

Source: The Woman the Mercury Astronauts Couldn’t Do Without

New stuff coming in C# 7.0

Mads Torgersen wrote a blog post highlighting what’s new in C# 7.0:

C# 7.0 adds a number of new features and brings a focus on data consumption, code simplification and performance.

The changes all seem to be in line with the recent trends of borrowing syntax sugar from other languages to C#. Nothing wrong with that: copy what’s good and shed what’s bad.

One of the changes is related to out variables. These are the C# way to deal with not being able to return multiple values (see below for good news on that front). It’s basically the same as passing by reference in, say, C. For instance:

int myOutVar;
changeMyOutVar(out myOutVar);

You could have the value of myOutVar set inside changeMyOutVar. Simple. What is changing in C# 7.0 is that you would no longer need to predeclare myOutVar:

changeMyOutVar(out int myOutVar);

The scope of the new variable will be the enclosing block. I have to say it: I don’t like it. It feels obfuscated to me. The variable doesn’t look like it should be in that scope. Compare with this popular Go idiom:

if err := DoSomething(); err != nil {
    return err;
}

The variable err is created inside the if and its scope is there as well. I know a lot of people who hate this for the same reason I don’t like the way the new out variables are to be created in C#. I find it much more clear in Go though.

The feature I absolutely loved to read about is tuples. Error handling in .NET is often done with exceptions, which I find clunky and cumbersome. With tuples, we might be able to move to something more Go-like:

(User, bool) FindUser(string username) {
    var found = _userList.Find(u => u.Username == username);
    if (found == null)
        return null, false;
    return found, true;
}

So we could do something like:

var (user, ok) = FindUser("someusername");
if (!ok) {
    // user not found, deal with this
}

Check his post for more features.

Millie 0.9.6, or “installers are hard”

I’ve been terribly busy with work lately and so I haven’t really had much time for my side projects. I did however managed to get a new version of Millie out of the door.

Got get it here.

Changes are mostly infrastructural though.

User “visible” changes:

  • Add .deb installation files for Linux
  • Add support for electron-builder
  • New settings system
  • Fix missing icon on Win64 installer
  • Split generation of 32- and 64-bit installers on windows

Minor changes and fixes

  • Merge branch ‘builder’ of github.com:robteix/millie
  • Ignore backups
  • Add missing dependency
  • Ignore main.js.map
  • Remove warning on unknown props
  • Cleanup
  • Move background declaration to MillieView
  • Stop loading old settings
  • Add script to generate release files
  • Remove log file left from first commit

That said, this release reminded me of how hard installers are to get right. Actually, they’re hard to do at all.

MacOS installers can basically only be made on macOS due to there not seeming to be decent implementations of DMG anywhere else. You can compile and create a ZIP file with your binaries, sure, but who wants that? To create a nice DMG, you need to be on macOS.

Windows is also hard to do in other systems. Not impossible, just annoying. You can get by with Mono in Linux or macOS but you need to get around a bug here and there. It works though.

Linux installers (meaning .dpkg and .rpm) are easy to do in macOS but barely doable on Windows.

In practice you end up having to create each installer on its own environment. Linux and Windows are easy to do with VMs, but you’ll need a macOS box eventually.

Windows has its own share of problems though. I hear they’re working on finally fixing their dumb limitations on path length but it’s definitely not there yet. This is important when working with things like npm that create paths hundreds of levels deep. Trying to something simple like deleting a node_modules directory on Windows is an exercise in frustration.

The installers for this release were all created in a Linux VM though. It was the closest thing I got to building it all in a single platform. No DMG for macOS though.

I’m sad today

So this is me today.

640px-Sad-pug

Years ago, my wife and I had a friends couple we worked with for some years. Someday they stopped talking to us. They refused to answer our calls or answer our emails. They never accepted out friend requests on Facebook.

We never knew why.

This happened over 10 years ago so naturally life moved on. From time to time, it happens that I see something from them on Facebook seen as we have a lot of friends in common, but neither of us acknowledges the present of the other.

I recently joined a Slack team and to my (and I’m sure his) surprise, my former-friend was there as well. Over the course of the next few weeks, we’d be talking in the same channel to other people but again, never directly to each other. I wanted to but I knew he was mad at me for something and I didn’t want to force it. What I did try doing was to engage in the channel as if nothing ever happened, just like everyone else.

But it was unconfortable. There was always that elephant in the room. So last Thursday I send him a message in private. I told him I never knew what I had done but that I apologized for whatever it was. I told him that he didn’t have to forgive me but I would really appreciate knowing what it was.

But he wouldn’t answer. So today I decided that there was no point in making two people uncomfortable all the time and I left the channel.

In the end, it’s no big deal. As I said, this was something that happened (whatever it was) over 10 years ago. But it makes me sad that I’ll never know what I did wrong.

(Image CC-BY-SA by Wikimedia Commons)

Une lettre ouverte à la madame qui a pointé son doigt vers ma fille

Conscient du fait que mon français n’est pas très bon (j’apprends), je pense cependant qu’il est important de l’écrire dans cette langue, car vous m’avez fait savoir que toute autre langue n’est pas acceptable.

Il y a quelques jours, j’étais chez un restaurant Valentine avec ma fille de six ans. Nous y étions allés parce qu’elle adore leur hot-dog et puisqu’elle avait fait un super effort à l’école ce jour-là, j’avais décidé de la récompenser. Vos raisons pour y être doivent être encore plus mondaines que ça.

Nous sommes arrivés au Québec depuis moins de trois mois et ma fille est toujours en train d’apprendre le français. Et bien qu’elle s’efforce de se faire comprendre par un monde qui ne la comprend pas, elle a encore des difficultés. Elle devient souvent frustrée. Et pourtant elle persévère. Sachez que je suis très fier d’elle.

Elle venait d’entrer à l’école avant les vacances d’été, juste pour apprendre le français. Un jour, les élèves devraient avoir un examen de mathématique et les enseignantes avaient décidé de sortir ma fille de la salle pour continuer à étudier le français. Ma fille a commencé à pleurer et supplier. Les enseignantes ne comprenaient pas pourquoi. Ils m’ont alors appelé et je suis allé à l’école. En y arrivant, nous avons finalement compris : elle se croyait punie et elle ne savait pas ce qu’elle avait fait pour le mériter. Elle implorait le pardon. C’est de ce genre de situation à laquelle elle doit faire face tous les jours.

Encore une fois, elle a six ans.

Elle a perdu toutes ses amies. Elle a dû laisser presque tous ces jouets. En tant que père, ça me brise le cœur de la voir en regardant des autres enfants qui jouent, parce que je sais qu’elle veut jouer avec eux, mais elle est souvent gênée à cause du français.

Je suis certain que vous serez d’accord avec moi quand je dis que ça n’est pas facile pour un adulte, et encore moins pour une petite fille. Mais elle fait un vrai effort là et je suis tellement fier d’elle. Vraiment fier.
Et c’est pour cette raison qu’il m’a fait tellement mal quand vous avez décidé de lui réprimander de ne pas parler français avec son papa.

Elle jacassait comme d’habitude quand vous l’avez interrompue pour me dire qu’il fallait parler français au Québec. Ça m’a surpris un peu, mais j’ai commencé quand même à vous expliquer qu’elle apprenait. Vous avez décidé de m’ignorer et de pointer votre doigt à une petite fille et de crier « en français ! »

Je suis un nouvel arrivant et je n’avais aucune idée, à ce moment-là, comment réagir. Je ne savais pas si vous auriez l’appui du reste des gens chez le restaurant ou pas. Mon instinct était juste de protéger ma fille de vous. Ma petite fille qui se protégeait derrière moi, intimidée par une madame qui partait en colère pour quelque chose qu’elle ne comprenait pas.

Et pourquoi ?

Je vous demande, madame, c’est à quoi exactement que vous vous attendiez ? Je comprends que vous considérez votre langue importante. En général, j’appuie l’idée que tout le monde doit être capable de se communiquer en français au Québec. Je pense que c’est absolument juste que personne ne vous demande de parler l’anglais ou d’autre langue, quelle qu’elle soit. Vous êtes au Québec et le français devrait être suffisant pour y vivre. Je suis d’accord avec tout ça.

Mais si ma fille veut parler à son papa en sa langue maternelle, qu’est-ce que vous avez à voir avec ça ?
Essayez de vous mettre dans notre place. Essayez de vous imaginer à un autre pays. Est-ce que vous arrêtiez de parler français avec vos enfants ou votre conjoint ? Soyez honnête.

Je ne sais vraiment pas ce que vous pensiez à réussir, madame, mais ce que vous avez réussi à faire c’est de me faire repenser le Québec et les québécois. Vous m’avez fait me demander si les québécois sont tous des colons. C’est ce que vous avez réussi, madame.

Mais même là, vous avez échoué.

Lorsque vous êtes partie, des gens chez le resto sont venus s’excuser de vous. Une femme a donné à ma fille des crayons et une feuille de papier pour qu’elle puisse dessiner afin d’arrêter de pleurer.

J’ai donc conclu que non, vous ne représentez pas le Québec. La plupart des québécois avec qui j’ai eu le plaisir d’interagir m’ont traité avec respect. La plupart des québécois avec qui j’en ai parlé m’ont dit la même chose : vous, et ceux comme vous, avez perdu la guerre. Vous êtes une relique d’un passé honteux de cette belle province. Vous représentez le passé.

Ma fille est l’avenir. Deal with it.