Search code examples
smlsmlnjcm

Resolve library conflict in SML/NJ Compilation Manager


I'm using SML/NJ 110.79, which includes support for new structures defined by the Successor ML project. Among others, the Fn structure.

As it happens, I already had an identically named structure in one of my personal project with utilities, which worked fine before 110.79.

With 110.79, for this .cm file:

group is
  $/basis.cm
  $SMACKAGE/sml-extras/v0.1.0/sources.sml.cm

I get the following error, though:

sources.cm:3.3-3.45 Error: structure Fn imported from $SMLNJ-BASIS/(basis.cm):basis-common.cm@155252(fn.sml) and also from $SMACKAGE/sml-extras/v0.1.0/(sources.sml.cm):src/fn.sml

Does anyone know how to resolve this conflict through the Compilation Manager. Ideally, my Fn structure will be able to "extend" the standard Fn by just open-ing it, but projects using the sml-extras library, will not see the standard Fn structure, only my extended version.

Is this possible? Do I need to wrap/re-export the whole basis.cm library in my sml-extras.cm project?


Solution

  • I managed to solve this by using what I believe is called an administrative library in the CM manual, §2.9.

    What that means precisely is to create an auxiliary .cm file that wraps the basis library and re-exports only the symbols we're interested in.

    sources.cm

    This is the main project file.

    library
      structure Main
    is
      (* Let's say this library redefines the Fn and Ref structures    *)
      (* and the REF signature.                                        *)
      $SMACKAGE/sml-extras/v0.1.0/sources.sml.cm
    
      (* This excludes out Fn, Ref and REF from the Basis library, but *)
      (* imports anything else.                                        *)
      amended-basis.cm
    
      main.sml
    

    amended-basis.cm

    This file imports $/basis.cm and then re-exports all of it except Fn, Ref and REF.

    group
      library($/basis.cm) - (
        structure Fn
        structure Ref
        signature REF
      )
    is
      $/basis.cm
    

    main.sml

    structure Main =
      struct
        open Fn (* sml-extras's Fn *)
      end
    

    The solution is based on the set calculus described in the CM manual, §4 and on the EBNF grammar from Appendix A.

    Another solution would have been to change sml-extras to re-export the whole $/basis.cm, while shadowing the conflicting symbols. However, in the interest of modularity I decided to go with the solution detailed above.