Blog

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.

Github’s Swift Style guide

Github has published a Swift Style Guide:

When you have to meet certain criteria to continue execution, try to exit early. So, instead of this:

if n.isNumber {
// Use n here

} else { return }

use this:

guard n.isNumber else {
    return
}
// Use n here

Feels very Go-like.

Invincible breaks my heart

Spoilers abound. You’ve been warned.

From the very beginning, Robert Kirkman maintained that Invincible was his attempt at doing the whole superhero thing right. There is a running gag in this book that on every cover (at least for a lot time if not since the beginning), they take a little jab at the superhero genre as done by other houses.

As news appeared that there would be a reboot, Kirkman was quick to declare that he was not going to be a dick to his readers and would not erase the whole timeline. By calling the arc “REBOOT?” with a question mark, he could not have made this more clearer. Also, the cover tagline:

img2015-12-16_04

And so we reach the end of the arc and Kirkman did keep his promise: the timeline was not erased. But maybe it should? That is the question that he leaves us with.

Mark is taken back to just before he gets his powers. He then deals the best he can with what he knows is coming: Nolan’s attempt at conquering the world for the Viltrumite Empire and the consequent deaths of so many in the process. That’s the “hero stuff” and although it’s well done, none of it will matter.

Mark has also to deal with being young again, living with his parents. His wife of many years now barely knows and definitely doesn’t care for him. And his daughter wasn’t born yet. How do you deal with this?

During the first two issues of the arc, Mark’s personal life was mostly a B plot. But in this final issue, it becomes central.

img2015-12-16_45

Mark gets a chance to go back to his original timeline, to his wife, to his daughter. But he’s asked for a sacrife. A hero’s sacrifice.

The beings that brought Mark here explain that by setting himself in another path, he can fix the future, he can fix all the things that happened to Earth in the original timeline. All he has to do is make the choice.

img18.21.24

But he says no. Mark wants to go back to his wife and daughter. There is nothing that can make him change his mind.

He doomed his planet and he is a disgrace, they say. I can live with that, he responds and goes back only to find desolation where the battle against Thragg is apparently finished – and apparently lost — I suppose we’ll learn more about that soon.

And of course, Kirkman had to throw one extra punch at the guy. As a father, the reveal at then end of what Mark has lost is heartbreaking.

Invincible remains the only book that has never once disappointed me in any of its arcs. This is amazing for a story ongoing for over 10 years and 126 issues.

Now excuse me while I go hug my daughter.

The Evolutionary Psychology Nonsense

I have a friend who is all into the whole evolutionary psychology fad. It’s useful when you want to rationalize bad behaviour. I once told him that evolutionary psychology was pseudoscience to which he replied saying that I was just trying to negate the world as-is.

But apparently I’m not alone, as Jonathan Marks writes (emphasis is mine) —

I can’t shake the feeling that the methodologies I have encountered in evolutionary psychology would not meet the standards of any other science.  For a notable example, it is apparently a revelation to evolutionary psychology that one cannot readily generalize about the human condition from a sample of humans that is Western, Educated, Industrialized, Rich, and Democratic. Perhaps this was news in psychology – creationist, evolutionary, or otherwise – but, sad to say, everybody else who works with cultural diversity knew that a really long time ago.