@jyapayne Thanks! I did't know generics are late binding.
This works as what I hope:
type
Animal* = concept a
a.id is int
a.sleep()
a.bark(int, int) is string
a.dance(string) is string
People*[T: Animal] = object
pet: T
# User defined type
Dog* = object
id: int
# User defined procs
proc sleep*(d: Dog) =
discard
proc bark*(d: Dog, b: int, c: int): string =
result = $(d.id + b + c)
proc dance*(d: Dog, b: string): string =
result = b
proc newDog*(id: int): Dog =
result.id = 1314
proc pay[T](p: People[T]) =
doAssert p.pet.bark(12, 14) == "1340"
doAssert p.pet.dance("dancing") == "dancing"
let d = newDog(12)
pay[Dog](People[Dog](pet: d))
Run