Mutually recursive types, recommended style?

When faced with a situation where you may need mutually recursive types like this:

mutable struct MyAgent <: AbstractAgent
    id::Int
    friendB :: AbstractAgent  # will always be AgentB type though
    #other fields
end

mutable struct AgentB <: AbstractAgent
    id::Int
    friendA :: AgentA 
    # etc
end

Is the internal constructor idiom still the recommended approach? (as described here: Mutually recursive type - General Usage - Julia Programming Language ) or would it be better to use use integers and look up the object from a collection when needed? (ECS-like style). Better means “more idiomatic” and “more performant”.

(Minor comment, I know I’m not answering your question: MyAgent is an abstract container type, you may want to convert it to a parametric type for performance reasons)

1 Like

Neither is more idiomatic than the other, mutually recursive or even just recursive types are actually very rare in practice. If you use inlineable isbits element types for those collections, you could cut down on allocations at the cost of targeted manual memory management e.g. integers specifying indices of a collection doesn’t inherently keep it alive or the specified elements valid.

1 Like