I have created a modified version of Kru02's interfaced. The original post is here: https://forum.nim-lang.org/t/2422
This version include more feature:
The most difficulty part of implementation is convert an interface to it's base interface, because it is must be done in runtime, and there is no any compile time information, so these information must be saved as runtime information.
Here is little example:
import interfaced
createInterface(Runnable):
proc run()
createInterface(Worker, Runnable):
proc work()
createInterface(Animal, Worker):
proc makeNoise(): string
proc legs(x: Animal): int
proc legs(x: Animal, m: int): int
proc greet(other: string): string
createInterface(BigAnimal, Animal):
proc say()
type
Dog* = ref object
name: string
age: int
Cat = ref object
name: string
proc makeNoise(d: Dog): string = d.name & " is barking"
proc legs(d: Dog): int = 4
proc legs(d: Dog, m: int): int = 4 + m
proc greet(d: Dog, other: string): string = "Welcome " & other & " from dog " & d.name
proc `$`(d: Dog): string = "Dog " & d.name
proc run(d: Dog) = echo $d, " will run"
proc work(d: Dog) = echo $d, " can work"
proc say(d: Dog) = echo $d, " is so big"
proc makeNoise(d: Cat): string = d.name & " is meoming"
proc legs(d: Cat): int = 8
proc legs(d: Cat, m: int): int = 8 + m
proc greet(d: Cat, other: string): string = "Welcome " & other & " from cat " & d.name
proc `$`(d: Cat): string = "Cat " & d.name
proc run(d: Cat) = echo $d, " is running"
proc work(d: Cat) = echo $d, " cannot work"
Dog.impl(Worker, BigAnimal)
Cat.impl(Animal)
proc takeRun(x: Runnable) =
x.run()
proc takeWork(x: Worker) =
x.work()
proc action(x: Animal) =
echo "I am ", x
echo x.makeNoise
echo "I have ", x.legs, " legs"
echo "I have ", x.legs(3), " more legs"
x.takeRun
x.takeWork
proc action(xs: seq[Animal]) =
for x in xs:
action(x)
echo ""
when isMainModule:
var xs = new_seq[Animal]()
let
d = Dog(name: "Bob").toBigAnimal
c = Cat(name: "Mimi")
xs.add d
xs.add c
action(xs)
That's a great set of improvements! Kudos.
One thing I wanted to share -- to stimulate further improvements -- is that when I looked at interfaced earlier, I ended up passing up on it because it's not possible to provide type parameters for the interface itself, and for interface methods. This limits the design of more generic interfaces, such as typeclasses.
e.g. if you wanted to define an interface such as an Iterator[T], or a method such as method map[U](f: T => U): Iterator[U].
I realize it could be a lot of work but I figured I'd share...
I am not familiar with Go interfaces. Can you please add a README that briefly explains what your module is doing, and add few examples too?
I see that you have an example.nim, may be put that inline in your README and explain that a little bit?
Thanks.