How to make a multi-level module hierarchy with (or without) Oasis

前端 未结 1 1033
误落风尘
误落风尘 2021-02-06 08:53

Suppose I have a set of modules each of which being rather \"bushy\" with submodules.

M1.X        M2.X        M3.X
M1.Y        M2.Y        M3.Y
M1.Z        M2.Z          


        
1条回答
  •  情书的邮戳
    2021-02-06 09:30

    With oasis

    The pack in oasis is a little bit broken, as it clobbers the namespace by including all paths into the search path. There is a long-living accepted bug request, but things are still where they are. But, if it worked correctly, it can help you, since it will create a library namespaces, allowing you to have modules with the same name in different folder. But, it doesn't work, so we should forget about it.

    The approach we have taken in BAP project was to mangle all module names with ugly bap_subproject_ prefix, that protects us from conflicts with our own modules, as well as from conflicts coming from external libraries. For each bap_subproject we have a folder with all implementation modules with mangled names and one umbrella module to rule them all. This module is stored in file bap_subproject.ml where it defines aliases for all modules and types that it is going to export. Usually it contains entries like:

    module X = Bap_subproject_x
    

    There is also a big Bap project, that unites all sublibraries under one namespace Bap.Std, and reexports everything it needs, so that after one open Bap.Std you have and access to Insn module that is defined in bap_disasm/bap_disasm_insn.ml[i]

    Without oasis

    Disclaimer: this solution may still work with oasis if you extend it with plugin.

    We've used this approach in one project, that is unfortunately closed source, so I can't provide a link. Each subproject lives in its own subfolder, within it own namespace (we have had parser module in each subfolder, without any clobber). For each subproject there is an mlpack file, in the top folder:

     root +
          |
          +-- expr.mlpack
          +-- expr -+
                    |
                    +- lexer.*
                    +- parser.*
                    +- ast.*
                    +- ...
          +-- cameo.mlpack
          +-- cameo-+
                    |
                    +- lexer.*
                    +- parser.*
                    +- ast.*
                    +- ...
    

    The contents of the expr.mlpack is:

       expr/Lexer
       expr/Parser
       expr/Ast
       ...
    

    ocamlbuild sees this expr.mlpack as a standalone module that has Lexer, Parser, etc submodules defined in it (and accessible as, e.g., Expr.Lexer). And there is no conflicts with a sibling project that also has Lexer, as well as no conflicts with ocaml-libs or any other external Lexer, since the expr folder is actually never included into the search path.

    If you need to add yet another layer to your system, like a pack for packs, then you have three choices:

    1. use the same approach recursively, i.e., create yet another super folder, that has mlpack or mllib files pointing to a child folder.
    2. just add big.mlpack that references all toplevel mlpack'ed modules
    3. create big.ml that reintroduces all modules.

    Last two approaches requires top-level packed modules to have different names of course. But usually this is fair enough.

    0 讨论(0)
提交回复
热议问题