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 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
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.