DEV Community

Discussion on: Zero-overhead interface exploration in Nim language

Collapse
shirleyquirk profile image
shirleyquirk • Edited on

hey, great post
the thing about Nim is that since it isn't strictly object oriented, interfaces aren't really necessary, as it separates functions and data inherently
So your 'Animal' class doesn't need to define barkimpl etc.
You just define

type
 Animal = ref object of RootObj
  id:int
 People = object
  pet:Animal
proc bark(a:Animal,b:int,c:int):string = $(a.id+b+c)

that's enough for

var people = People(pet:Animal(12))
assert people.pet.bark(13,14) == $(12+13+14)

to work without any messing about with helper macros.
extending:

type
 Dog =ref object of Animal
   did:string
   name:string
let fido = Dog(did:"First",id:777,name:"OK")
people.pet = fido #works
doAssert people.pet.id==777
doAssert people.pet.Dog.name=="OK"     #cast to Dog to access .name
doAssert people.pet is Animal                     #still Animal
proc bark(d:Dog,b:int,c:int) = $(d.id+2*b+3*c)        
doAssert people.pet.bark(13,14) == $(777+13+14)      #Animal.bark
doAssert people.pet.Dog.bark(13,14) == $(777+2*13+3*14) #Dog.bark
Collapse
xflywind profile image
flywind Author

Thanks for your comments!

Collapse
shirleyquirk profile image
shirleyquirk • Edited on

Just seen this:
nimble.directory/pkg/interfaced
I think it provides the semantics you are looking for, really cleanly.
Works by creating a vtable under the hood, just like other oo languages do.

Pretty crazy that Nims macro system makes it possible to add such a feature to the language.

Thread Thread
xflywind profile image
flywind Author

Thanks!

Thread Thread
shirleyquirk profile image
shirleyquirk

Oh man, they just keep coming:
This hidden gem is undocumented, but provides the same functionality without the overhead of a vtable.

github.com/mratsim/trace-of-radian...