Interfaces In Nim

14 May 2016

One of the things you're going to run into when you first use nim, is that it lacks interfaces. As far as I'm concerned, that's a big limitation. However, there is a pattern available to us, which, as far as I can tell, is the "nim way."

The trick is to use a tuple of procs. Let's look at an example. First, we'll create our "interface":

type
IFileSource = tuple[
read: proc(path: string): string
]

The above creates a new type, IFileSource which is a tuple containing a single key, read. read references a procedure which takes a path to a file (as a string) and returns the file's contents (also as a string).

From the execution point of view, this behaves just like an interface. We can create a procedure which takes an IFileSource and call its read method:

proc process(fs: IFileSource) =
let config = fs.read("config")
...

Hopefully, every thing is clear. Next, let's create an implementation which reads from the local file system:

All that's left is to associate our implementation with our interface. The little mental barrier you need to tear down is that this is an explicit / manual process. By that, I mean we need to create a procedure that converts one to the other:

I'll confess that it took me a few minutes of staring at the example I found before understanding it. But it's quickly become second nature. Having said that, I've seen a couple comments suggesting that Go-like interfaces (easily one of Go's best features) could be added in the future. That would be nice.