you don't need to mix generics and inheritance, one or the other should be 
sufficient 
    
    
    type
      BaseNode = ref object of RootObj
        someEdge: BaseEdge
      BaseEdge = ref object of RootObj
        someNode: BaseNode
    
    type
      myNode = ref object of BaseNode
        extraNodeField: int
      myEdge = ref object of BaseEdge
        extraEdgeField: int
    
    var v = myNode(extraNodeField: 7)
    v.someEdge = myEdge(extraEdgeField: 9)
    echo v.repr
    
    
    Run

> I could add a generic payload: T field instead (and put all extra fields 
> there), but that means I would need to write node.payload.someExtraNodeField 
> each time I want to access it (and also it would require extra memory).

you can write templates and procs to reduce boilerplate, overloading the `[]` 
operator might be useful

containers don't take up more memory than their contents (modulo padding), 
inheritable objects have an extra pointer.
    
    
    type
      Container[T] = object
        payload: T
      
      Base = object of RootObj
      Inherited = object of Base
        payload: int
    
    let x = Container[int]()
    let y = Inherited()
    
    echo sizeof(x)  #8
    echo sizeof(y)  #16
    
    
    Run

Reply via email to