If I have 2 routines in different files that are mutually recursive, OCaml complains if they try to refer to each other in the obvious, naive way. But, as the manual describes, you can around get limitation fairly simply like this:
Use a reference to hold one of the two functions, as in:
mod1.ml:
let forward_g =
ref((fun x → failwith “forward_g”) : )
let f x = … !forward_g …
mod2.ml:
let g y = … Mod1.f …
let _ = Mod1.forward_g := g
On the other hand, AFAICT, it seems that mutually recursive types must be defined in the same file and joined with an “and”. For example, if I have existing code defining 2 records that now need to become mutually recursive, I must refactor the types so they are in the same file.
Or (the case I actually encountered) suppose I have 2 source files A and B respectively defining typeA and typeB. If A calls a routine in B, then if I try to have typeB refer to typeA, the linker will again complain. I’d need to move typeB into A.mli or create a new .mli file with both typeA and typeB.
Is there any way to do this without moving type definitions between files? It would be helpful if there was a way to do so without having to refactor. OTOH this may be difficult to impossible to support.
PS It would be great if Ocaml permitted forward reference to functions defined in the same file without special syntax. (Or second best, with a forward declaration). Fairly often I find I need to reorder routines in a file in order to support new functionality. Sometimes this is nontrivial. The resulting block moves in the git history suggest that the changes were more significant than they are. In addition, the git history doesn’t make it easy to find changes that were made to a moved routine.