You can use F # support for recursive initialization even when instantiating an abstract class:
let makeParent() = let rec children = seq [ Child(parent); Child(parent); Child(parent) ] and parent = { new Parent() with member __.Children = children } parent
When compiling the code, F # uses lazy values, so the value of children becomes the lazy value, and the children property refers to the value of this lazy calculation. This is great because it can first instantiate the Parent (referring to the lazy value) and then actually build the sequence.
Performing the same action with the records will not work just as well, because none of the calculations will be postponed, but it works pretty well here, because when creating a Parent this sequence is actually not available (if it was a record, this will be the field to be evaluated).
The F # compiler cannot tell (in general) whether this is correct, therefore it gives a warning that can be disabled using #nowarn "40" .
In general, I think that using let rec .. and .. to initialize recursive values ββis good - it is a bit limited (one of the links should be delayed), but it forces you to isolate the recursive links, and I think it simplifies your the code.
EDIT To add an example where this might go wrong - if the Child constructor tries to access the children collection of its parent, then it forces the lazy value to be evaluated before it can be created, and you get a runtime error (which is what the warning says). Try adding this to the Child constructor:
do printfn "%d" (Seq.length parent.Children)
source share