I am still pretty new to Nim, but it is fast becoming my #1 preferred language. I think it is elegant in some ways. But one thing that feels really cumbersome to me is methods for generic "classes", such as this example dictionary:
type Dictionary[Key, Value] = ref object
...
proc insert[Key, Value](this: var Dictionary[Key, Value], key: Key, value: Value) =
...
proc find[Key, Value](this: var Dictionary[Key, Value], key: Key): Value =
...
I have tried to write a "class" macro, but ran into some issues. Is there an alternative that I haven't found, or should I just come to terms with this part of the language?
class Dictionary*[Key, Value]:
field*: Type
proc insert(key: Key, value: Value) =
...
should become
type Dictionary*[Key, Value] = ref object
field*: Type
proc insert[Key, Value](this: var Dictionary[Key, Value], key: Key, value: Value) =
...
or something along those lines, was my thinking. One of the specific issues I encountered was that this syntax:
class MyClass*:
results in an error "Error: expression expected, but found ':'", and I haven't found a good way around it.An alternative syntax for the procedures' signatures in the example, maybe is more to your taste:
proc insert(this: var Dictionary, key: Dictionary.Key, value: Dictionary.Value) =
...
proc find(this: var Dictionary, key: Dictionary.Key): Dictionary.Value =
...
@Swend
class MyClass*: results in an error "Error: expression expected, but found ':'", and I haven't found a good way around it.
You actually can get that syntax to work like this:
class Foo as object:
...
class Bar* as ref object:
...
That said, it's annoying and there's one big flaw with using a class macro like that right now: interdependent types can only be defined in a type section. However, we can do OOP in Nim just fine in a more "Rust like" fashion. Eg:
type
Person = object
name: string
age: float
impl Person:
proc greet =
echo "Hello, I am ", name, "."
echo "I'm ", age, " years old."
var bob = Person(name:"Bob", age:45)
bob.greet()
This way has a couple of advantages over the class macro:
Here's some working example code. of an impl macro. It needs to be improved a bit to support generics.. but it might help you start.