What is an unsafe functor?

I am getting the following error:

Error: Cannot safely evaluate the definition of the following cycle
       of recursively-defined modules: Value -> Value.
       There are no safe modules in this cycle (see manual section 12.2).
  Module Value defines an unsafe functor, Monadic .

However, section 12.2 of the manual doesn’t say anything about what an “unsafe functor” is. I have looked through my code and I don’t think I have any unsafe values in the sense defined in the manual (I could try to post a MWE if it would help). And googling for “defines an unsafe functor” in quotes yields only two results from the entire Internet, neither of them helpful (one of them looks like it might be the source code for OCaml, the other I can’t find the phrase on the actual page).

All functors are considered as unsafe modules for the purpose of the recursive module check (there is a comment saying “can we do better ?”, probably left there a few decades ago). It doesn’t matter if the input or output signatures are safe or not.

Okay, thanks. It would be nice if that were documented, but at least now this discussion will be a third Google hit for “defines an unsafe functor”. Can you say anything about why functors are considered unsafe?

The following might be useful:

A proposal for recursive modules in Objective Caml
Xavier Leroy
INRIA Rocquencourt
Version 1.1, May 13, 2003

especially footnote 2 on p6:

² Notice that a functor is always unsafe. The reason for this is that the size of the closure representing the functor at run-time cannot be determined from its type, thus preventing the construction of a suitable initial value in phase 1 of the compilation scheme described later.

Thanks! I don’t know what “the closure representing a functor at run-time” is, or what its “size” is, or why that matters, but it sounds like it’s an implementation detail rather than a conceptual restriction or inconsistency.

Note that the whole notion of unsafe modules is an implementation detail. The exact definition of a “safe” module is “a module for which we have a hack allowing it to be initialized with a wrong value of the right type and patched later”. It excludes functors not because it is impossible to pre-initialize them but because we haven’t implemented it (and patching functions is a bit more complex than patching structures). In the same vein, a module that contains non-functional values whose definition does not depend on the recursive modules could be made safe, and there are traces of attempts to do that in the compiler’s code, but currently it’s rejected.
If you have a use-case for a recursive functor, I would encourage you to post an issue about it. I can think of a few ways to actually implement it, so if there is no strong disagreement it might end up being accepted.

Well, I thought I had a use-case when I posted this question, but I’ve since realized there is a simpler way to do what I want. So I probably won’t go ahead and post an issue right now, although I might change my mind again later. Thanks!