-
Notifications
You must be signed in to change notification settings - Fork 1
Module resolution mechanism
The standard ways of importing modules (structures) in SML are, open statement or alias, like the following.
open List
structure P = OS.ProcessHowever, there are some shortcomings of this approach, due to the fact that the module (structure) path does not correspond to file structures.
- Module dependency is not explicit, which makes code browsing difficult. You cannot jump to the file defining
OS.Process. - A build system needs extra information to get dependency relationship between source files. For example, mlton requires *.mlb files, whereas smlnj asks for *.cm files.
- No guard from structure path clash. Any files could define structure like
OS.Process, leading to unexpected clashes.
The solution to this is easy, and well practised in other languages. That is, a convention of link between source file structure and module path. Specifically, the module path OS.Process, corresponds to a file "OS.sml", or "Process.sml" under the directory of "OS". In other words, the compiler searches for a source file matching the module path following a convention. The convention in Haskell can be borrowed.
Another pitfall we need to work around, is relative module path of substructures. For example, if Process is a substructure of OS in OS.sml, and a snippet is like below
open OS
structure P = ProcessIf the compiler tried to search source file Process.sml, it probably won't have any luck. So we need to add another rule to the source file search mechanism: only searching for files matching a module level object (structure, signature or functor) if the object is not in current scope.
A potential implementation of this mechanism may be source file rewriting, by injecting use "dependency.sml" statements to source files. If this noninvasive is possible, then we could apply it to work with existing sml compilers. Otherwise, we have to write a specific sml compiler for it.