On Monday, 12 August 2019 at 22:48:43 UTC, Bert wrote:

Making a field static is effectively a global variable to theclass.I have a recursive class structure(think of a graph or tree)and I need to keep a global state for it, but this stateactually needs to be different for each tree object. The reasonfor this is that structurally it will not change per tree andif it it is not static then it wastes space unnecessarily.class X { X[] x; static State s; }making s non-static has the problem that every X will allocatestorage for s wasting space since for any instance chain of X'sthey will all have the same s. Making it static though thenmakes it the same for all instance chain's of X, of which itshould be local to each.One way around this is to use an dictionary that associateseach state to each instance chain.That is there is a initial X that is the parent of the chainand we can then associate a state to it's address, any otherchain will have a different initial X and so we can get a newstate.class X { X[] x; static State[X] s; }This is not a huge difficulty to do but does require findingthe initial X to use, which is not difficult but wastes cyclesfor large chains. There will, of course, be a constructor thatconstructs a chain and creates a new state for it and updates s.Is there any way to do this more naturally in D?

`First: Are you low on memory? Is traversing the tree actually`

`slow? Since you don't know which of these issues to prioritize,`

`in all likelihood the answer to both questions is no, and you`

`should use the solution that's easier to read.`

`Of course, that's not the answer you want to hear. Let's consider`

`the alternatives:`

`1) Embed it in each node. Costs 1 pointer's worth of memory per`

`node. Very fast. Very easy to understand.`

`2) Use a dictionary with entries for each node. Costs more than 1`

`pointer's worth of memory per node. Fast, but not quite as fast`

`as 1). 1) is almost definitely a better option.`

`3) Use a dictionary with entries for each root node. Costs more`

`than 1 pointer's worth of memory, but per tree instead of per`

`node. Requires traversal of the tree to find the root, so slower`

`than both 1) and 2), especially for deep hierarchies. Complicated`

`code.`

`4) Use a derived class for the root node (class RootX : X { State`

`s }). Still requires traversing the tree to find the root, likely`

`via a virtual method. Also requires a bit more work setting up`

`the tree. Might be faster than 3), definitely smallest memory`

`footprint. Relatively easy to follow.`

`There may be other options, but from the above I'd go with either`

`1) or 4).`

`Now, I've noticed that X doesn't have a pointer to its parent, so`

`traversing the tree to find the root is currently impossible. If`

`this is true, and you have no other use for traversing up the`

`tree, then 1) is the way to go, as 2) is almost never a better`

`option, and 3) and 4) requires adding a parent pointer so you'll`

`pay the memory price anyway.`

-- Simen