Why not function/module declaration hoisting support?

Hoisting - MDN Web Docs Glossary: Definitions of Web-related terms | MDN

I made a big recoil state graph, many selectors depend each other but not cyclic. because not have hoisting so I can’t make sub-module for types.

Hoisting is a distinctly JavaScript thing. But the rec keyword can be used for both types and modules! The only caveat is that it requires an explicit type when used to define a module.


1 Like

Note that recursive modules might get removed in the future: Roadmap | ReScript Community

That would destroy complex module organization

1 Like

For most other changes there’s a migration path and usually an automated code upgrade. When removing recursive modules it will be interesting to see if or how they can avoid breaking code that uses it.

1 Like

For cycles in small scopes you can use let rec.
In general you want to avoid cycles between files, if you do have cycles across files, a common pracice would be:

let used_by_b = ref (fun _ -> assert false)
let f_x = B.use_b_fun
A.used_by_b.contents <- (fun ...)
let use_b_fun = ...

Here A and B have cycles but you can avoid it by delay the initialization

I’m not especially in favor of removing recursive modules, but I think it’s worth noting that they’ve always been experimental, even in newer OCaml versions. Their exact definitions aren’t finalized, and their limitations (such as needing to annotate them) adds a lot of friction. In general, if a language makes it hard to use a feature, then you probably want to avoid that feature unless you have a good reason not to.

I know recursive modules have existed for a while, and some people use them, but I don’t think they’ve ever been especially recommended. Personally, I haven’t encountered a problem where recursive modules solved it better than recursive let rec bindings.

My point is that, whether the compiler supports it or not, I would always try other options before using recursive modules anyway.