One of the things that intrigued me about Nim was it's object system, you could create value, reference and pointer types with/without inheritance. As I understand it, an important distinction between ptr and ref classes is that ref classes are managed by the garbage collector while ptr classes have to be manually allocated and deallocated.
In this case for me that _is_ the distinction between both of them, I see inheritance from a ptr class as the same as inheritance from a ref class and polymorphism in the same way: type: Animal = ptr object of RootObj Cat = ptr object of Animal var x: Animal = create(Cat) Run But I also want to be able to dispatch against Cat (x) at runtime, so send it as a parameter in a function marked with Animal but within that function call the cat method and allow the right method to be dispatched. In exactly the same way as in my kernel function: proc calculateKernelMatrix*(K: AbstractKernel, data: Matrix[F]): Matrix[F] = let n = int64(ncol(data)); var mat = Matrix[F](data: newSeq[F](n*n), dim: @[n, n]); for j in 0..<n: for i in j..<n: var tmp: F; mat[i, j] = kernel(K, data.col(i), data.col(j)); mat[j, i] = mat[i, j]; return mat; Run It doesn't matter that AbstractKernel is a ref or ptr type, without polymorphism I can't runtime dispatch the right method at the kernel function. This can not happen without inheritance and polymorphism, at runtime overriding the parent method with the child method while providing the same interface in the usual way. At compile time yes you could just use procs but you need polymorphism for runtime dispatch.