The direct way to separate the parent's initialization is not use methods since there's no need for dynamic dispatch, even though an OOP language would use super in such a case: type ParentObj* = ref object of RootObj parentField: int ChildObj* = ref object of ParentObj childField: int proc init*(parent: ParentObj, n: int) = parent.parentField = n proc init*(child: ChildObj, n: int) = child.ParentObj.init(123) child.childField = n proc newChild*(value: int): ChildObj = new result result.init(value) var child = newChild 567 echo "child parentField: ", child.childField echo "child childField: ", child.parentField Run
What `procCall` is for, is these circumstances where some specific resolution is static and known, but where you're using methods because the resolution is usually dynamic. I can't think of a good example of that, so here's typical OO-example fare: import std/sequtils type Animal = ref object of RootObj noisiness: int Dog = ref object of Animal method bark(a: Animal) {.base.} = inc a.noisiness method bark(a: Dog) = echo "A dog barks" procCall bark(Animal(a)) proc thunder(area: var seq[Animal]) = for animal in area: animal.bark() # late addition type Cat = ref object of Animal method bark(a: Cat) = echo "A cat meows" procCall bark(Animal(a)) var area: seq[Animal] = @[new Dog, new Dog, new Cat] thunder area thunder area thunder area echo "Noisiness: ", area.foldl(a+b.noisiness, 0) Run