Roberto Selbach

About |  Blog |  Archive

Blog

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.

Best icecream I’ve ever had

Years ago, I was part of a project that went completely off the rails. A little context: we were a services company and we had local offices in cities all over the country. My team provided 2nd-level support which means we often had the PMs call us from those via an annoying Nextel radio.

I won’t go through the details but suffice it to say this project envolved one such branch going rogue and committing actual fraud, with criminal proceedings and all. People were on the edge, and the relationship with that branch was increasingly hostile. There was also an internal power struggle in the company between some directors at that point. In other words, a clusterfuck I’ll always cherish, if by cherish you mean hate hate hate. Anywho…

One time, there was a national holiday on a Thursday and we were going to make it a long weekend. As customary, I communicated with all the PMs about contigency plans. This PM then told us that we could not take Friday off because the customer wanted us to fly over there. We were supposed to be at the customer’s site early Friday morning. That meant we would have to fly Thrusday afternoon. I wasn’t happy.

It immediatly felt arbitrary too. As I said, the relationship was not good and we suspected he was just trying to cost us our days off. I knew enough of the customer to be fairly sure they would not have requested us that Friday. Why did the customer want us then? There was nothing yet on production and if it was just to show progress, surely we could move it to Monday. At worst, can’t we make it over the phone? No, no, no, he said. The customer was adamant that we be there on Friday. Sucked to be us.

So we flew over Thursday afternoon and on Friday morning we headed to the customer’s offices only to find it closed. They too had made it a long weekend and wouldn’t be back until Monday.

Normally I would be furious over the waste of time but to be honest, both I and my colleague smiled at that. It confirmed that the PM just tried to screw us and the customer have never asked for us. We headed back to the local office.

Before coming in, we both bought ourselves some icecream. My friend stayed in the little garden in front and I went in. The PM immediatly saw me and demanded to know why I wasn’t at the customer yet. I didn’t answer. Instead I grabbed the Nextel radio and headed back out with the PM following. I then sat down on the grass and called my director. Smiling and staring at the PM, I told him about the office being closed. The PM’s face froze when my director asked to talk to him.

We sat outside under the sun, enjoying our icecreams while the PM got shouted at. It was the best icecream I’ve ever had.

Is it really as bad as it looks?

Hi, I have a question

Do you ever not?

“Learning never exhausts the mind.”

Leonardo DaVinci? I’m proud of you. Go ahead.

Thank you. I’ve been reading all these horrific news stories about the Olympic games and Rio…

Oh that. Yeah, I’ve been getting asked that question regularly lately.

Is it really that bad?

Yes and no. There is a lot of sensationalism out there. But it’s bad and, at least to us Brazilians, not at all unexpected because Rio is widely known as a hellhole among us.

Years ago, when the games were announced, most of us in Brazil expected the worst. Rio is widely perceived by Brazilians as a hellhole.

I spent a whole month there once because of work and it left a strong mark in me. I’ve seen people being mugged, a dead body was left outside my hotel one night, I was in the middle of a shooting between rival gangs, and — crème de la crème — one day some big shot drug trafficker was killed in jail and what followed was, to me, surreal. The city is beautiful though.

What happened?

All thoughout that day, people kept telling me about the news of this guy who got killed. I could not care less, to be honest. But at the end of the day I finally understood when I tried leaving the office and people said I was nuts. I wasn’t allowed to go because the drug gangs issued a curfew on the city.

A. Curfew. On. The. City.

At times like that, commerces close their doors all over the place and the police completely disappears.

That’s insane! How is anyone safe during the games?!

Well, here’s where I point out that it’s probably not as bad as you’d think.

Wait what

Hold on. First of all, it is not in the gangs’ interest to attract international attention. They already have full control over the city, the police, etc. It’s in their best interest to wait the games out and then continue with business as usual. I doubt there will be problems with the drug traffic.

Second, there will be 50,000 security personnel there. FIFTY THOUSAND. And again, it’s in the powers that be’s interests that foreigners have a good time there. It will suck for people from Rio who will be hounded by the police and the army, though.

Just a couple of weeks ago the Brazilian Congress passed a special law granting de facto immunity to members of security forces who happen to commit crimes against civilians during the games. It’s going to be fun.

Wait what? Immunity

De facto. What the law does is transfer the authority of judging these cases to militaty justice. In practice, it means immunity. And the reason for the law was exactly to allow the police and the army to trump people’s rights in order to keep the peace. It’s so very Rio.

And terrorism?

Yeah, I don’t know. As we’ve seen these past weeks, you don’t need much to kill people. A rental truck is enough. So yes, there might be something. Then again, 50,000 security personnel. I’m guessing there might be easier targets out there. In short, I don’t know but I don’t think the risk is high enough to worry about it.

What will be horrible is already happening and mostly hidden from foreigners. It’s the human rights abuses against the poor. That to is very Rio. They’re make every effort to hide the poor and prevent them from being seen, no matter the cost. Thousands have been forcebly relocated already.

And in the end, what for? The city (and its people) won’t come out better after the games than before.

It’s depressing

Indeed.

How do I add an unknown attribute to an element in ReactJS?

There’s this project I’ve been working on in ReactJS and Chrome and I needed to use a <webview> component. In case you’re not familiar with <webview>, it looks something like this —

 <webview src="https://robteix.com"></webview>

One of the coolest features of <webview> is the ability to isolate scope or partition it. When you use a partition, all cookies, local and session storage, etc, will be stored separately from other partitions. All you need to do is add the partition attribute. So I had something similar to this inside one of my components —

return (
 <webview id="foo" 
 src="https://somewebsite.com/"
 partition="persist:foobar" />
);

To my surprise, multiple <webview>s were sharing the same session data. Not good. A quick glance in the app storage directory told me that no partition was being created. What’s wrong?

We can look at the HTML output for hints —

 <webview id="foo" src="https://somewebsite" class="MyComponent__component___3U2KV" data-reactid=".0.0.0.2:$MyComponent.0" tabindex="-1"></webview>

No partition to be found. The reason is React doesn’t know what to do with that attribute and as a result it is not output. There are good reasons for this, but the main one is that properties may (and often do) work differently accross browsers and React needs to be able to deal with this.

But how can we add the attribute that we need then? You could add some JavaScript to get the element but that’s not very reactive. The reactive way to do this is to leverage ref, which can provide a reference to an element.

 <Element ref={somevar} />

In this code, somevar will hold a reference to <Element>. Better yet, just use a function instead.

 <Element ref={function(e) { e.Something(); }} />

Or in ES6 syntax.

<Element ref={(e) => e.Something() } />

Which finally takes us to our problem: how do we add the partition attribute? Easy peasy.


return (
 <webview id="foo" 
 src="https://somewebsite.com/"
 ref={elm => elm && elm.setAttribute('partition', 'persist:foobar')} />
);

And that’s it, a simple way to add unknown attributes to elements in React.

Clashing method names in Go interfaces

I wrote about how the Go and C# compilers implement interfaces and mentioned how C# deals with clashing method names but I didn’t talk about how Go does it, so here it is.

Two interfaces with the same method name that need to behave differently is very likely a sign of bad API design and we should fix it instead. But sometimes we can’t help it (e.g. the interfaces are part of a third-party package). How do we deal with it then? Let’s see.

Given two interfaces

type Firster interface {
    DoSomething()
}

type Seconder interface {
    DoSomething()
}

We implement them like this

type MyStruct struct{}

func (ms MyStruct) DoSomething() {
    log.Println("Doing something")
}

We can run this little test here to verify that MyStruct implements both interfaces.

But what if we need DoSomething() to do something different depending on whether MyStruct is being cast as Firster or Seconder?

Go doesn’t support any kind of explicit declaration of interfaces when implementing methods. We can’t do something like, say

type MyStruct struct{}

func (ms MyStruct) Firster.DoSomething() {
    log.Println("Doing something")
}

func (ms MyStruct) Seconder.DoSomething() {
    log.Println("Doing something")
}

That won’t work. The solution is to wrap MyStruct with a new type that reimplements DoSomething(). Like this

type SeconderWrapper struct {
    MyStruct
}

func (sw SeconderWrapper) DoSomething() {
    log.Println("Doing something different")
}

Now when we need to pass it to a function expecting Seconder, we can wrap MyStruct

ms := MyStruct{}
useSeconder(SeconderWrapper{ms})

That will run the DoSomething() from SeconderWrapper. When passing it as Firster, the original DoSomething() will be called instead. You can see this in action here.

Interfaces in Go and C#

I make no secret of the fact that I love Go. I think it’s a wonderfully designed language and it gave me nothing but pleasure in the years I’ve been working with it full time.

Now however I am working on a project that requires the use of C#, which prompted me to realize something.

When people ask about Go, most people talk about channels and concurrency but I think one of the most beautiful aspects of Go is its implementation of interfaces.

To see what I mean, let’s define a simple interface in Go.

type Greeter interface {
    Hello() string
}

Now say we have a type that implements this interface

type MyGreeter struct {}

func (mg MyGreeter) Hello() string {
    return "Hello World"
}

This is it. myGreeter implicitly implements the Greeter interface and we can pass it along to any function that accepts a Greeter.

func doSomethingWithGreeter(g Greeter) {
    // do something
}

func main() {
    mg := myGreeter{}
    doSomethingWithGreeter(mg)
}

The fact that the implementation is actually important, but we’ll get to that. Let’s first do the same thing in C#.

interface Greeter
{
    string Hello();
}

And then we create a class that implements the interface.

class MyGreeter
{
    public string Hello()
    {
        return "Hello world";
    }
}

We quickly find out that the compiler doesn’t like this.

public static string doSomething(Greeter g)
{
    return g.Hello ();
}

public static void Main (string[] args)
{
    MyGreeter mg = new MyGreeter ();
    doSomething (mg);
}

The compiler complains that it cannot convert MyGreeter to type Greeter. That’s because the C# compiler requires classes to explicitly declare the interfaces they implement. Changing MyGreeter as below solves the problem.

class MyGreeter : Greeter
{
    public string Hello()
    {
        return "Hello world";
    }
}

And voilà, everything works.

Now, we might argue that it is not much different. All you have to do is to declare the interface implemented by the class, right? Except it does make a difference.

Imagine that you cannot change MyGreeter, be it because it’s from a third-party library or it was done by another team.

In Go, you could declare the Greeter interface in your own code and the MyGreeter that is part of somebody else’s package would “magically” implement it. It is great for mocking tests, for example.

Implicit interfaces is an underrated feature of Go.

Update: someone on Twitter pointed me to the fact that C# not only also has implicit interfaces but that this is the default state of things. That is true in a literal sense, but it’s not the same thing.

Imagine in our C# above, we have a second interface.

interface IAgreeable
{
    string Hello();
    string Bye();
}

(Yes, I was also told that in C# we should always name interfaces like ISomethingable. I disagree but there it is.)

We then implement our class thusly

class MyClass : Greeter, IAgreeable
{
    public string Hello() {
        return "Hello world";
    }
    public string Bye() {
        return "Bye world";
    }
}

It now correctly implements both interfaces and all is well with the world. Until, that is, the Hello() method needs to be different for each interface in which case you will need to do an explicit implementation.

class MyClass : Greeter, IAgreeable
{
    string Greeter.Hello() {
        return "Hello world from Greeter";
    }
    public string Hello() {
        return "Hello world from !Greeter";
    }
    public string Bye() {
        return "Bye world";
    }
 }

And then the compiler will call the appropriate Hello() depending on the cast.

public static string doSomething(Greeter g)
{
     return g.Hello ();
}
public static string doSomethingElse(IAgreeable g)
{
    return g.Hello ();
}
public static void Main (string[] args)
{
    MyClass mg = new MyClass ();
    Console.Out.WriteLine(doSomething (mg));
    Console.Out.WriteLine(doSomethingElse (mg));
}

This will print

Hello world from Greeter
Hello world from !Greeter

Personally I consider two interfaces with clashing method names that need to behave differently a design flaw in the API, but reality being what it is, sometimes we need to deal with this.