@Udiknedormin: I meant right now, since VTable are not available of course.
@monster: It is not safe as is, you must ensure your chain of Msg and MsgBase pointers have the same lifetime (by putting them in a seq for example). Otherwise if they are created in different functions, the previous MsgBase would not exist anymore. Using concepts, doesn't work yet though because no VTable. type QueueID* = distinct uint16 MsgBase* = concept x x.previous is ptr[MsgBase] x.sender is QueueID x.receiver is QueueID Msg*[T: not (ref|string|seq)] = object previous: ptr[MsgBase] sender: QueueID receiver: QueueID content*: T proc initMsg[T](previous: ptr[MsgBase], sender, receiver: QueueID, content: T): Msg[T] = result.previous = previous result.sender = sender result.receiver = receiver result.content = content let a = initMsg(nil, 1.QueueID, 2.QueueID, 42) echo a # Error: cannot instantiate: 'MsgBase'