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:

from os import nil type LocalFileSource = object root: string proc read(fs: LocalFileSource, file: string): string = return readFile(os.joinPath(root, file))

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:

proc toFileSource(fs: LocalFileSource): IFileSource = return ( read: proc(file: string): string = fs.read(file) )

To use it, we'd do:

let fs = LocalFileSource(root: "./data/") process(fs.toFileSource())

For simple interfaces like this one, we can [arguably] simplify the code by replacing our LocalFileSource with a closure:

proc localFileStore(root: string): IFileSource = return ( read: proc(file: string): string = readFile(os.joinPath(root, file)) ) process(localFileStore("./data/"))

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.